127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber/*
227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * Copyright (C) 2009 The Android Open Source Project
327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber *
427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * you may not use this file except in compliance with the License.
627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * You may obtain a copy of the License at
727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber *
827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber *
1027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * Unless required by applicable law or agreed to in writing, software
1127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * See the License for the specific language governing permissions and
1427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber * limitations under the License.
1527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber */
1627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber//#define LOG_NDEBUG 0
1827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#define LOG_TAG "AwesomePlayer"
1927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <utils/Log.h>
2027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
214ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber#include <dlfcn.h>
224ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber
237a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "include/ARTSPController.h"
2427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include "include/AwesomePlayer.h"
257a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include "include/LiveSource.h"
261314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber#include "include/SoftwareRenderer.h"
274d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber#include "include/NuCachedSource2.h"
284d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber#include "include/ThrottledSource.h"
2954d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber#include "include/MPEG2TSExtractor.h"
3027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
3157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "ARTPSession.h"
3257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "APacketSource.h"
3357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "ASessionDescription.h"
3457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "UDPPusher.h"
3557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
36a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber#include <binder/IPCThreadState.h>
3727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/AudioPlayer.h>
3827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/DataSource.h>
3927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/FileSource.h>
4027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/MediaBuffer.h>
41c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber#include <media/stagefright/MediaDefs.h>
4227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/MediaExtractor.h>
4327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/MediaDebug.h>
4427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/MediaSource.h>
4527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/MetaData.h>
4627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber#include <media/stagefright/OMXCodec.h>
47c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber
48000479f9e325b4e426a67033abd92d47da412725Mathias Agopian#include <surfaceflinger/ISurface.h>
49000479f9e325b4e426a67033abd92d47da412725Mathias Agopian
507a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber#include <media/stagefright/foundation/ALooper.h>
51202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber
5227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubernamespace android {
5327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
5487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huberstatic int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
5587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huberstatic int64_t kHighWaterMarkUs = 10000000ll;  // 10secs
56a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huberstatic const size_t kLowWaterMarkBytes = 40000;
57a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huberstatic const size_t kHighWaterMarkBytes = 200000;
5887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber
5927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstruct AwesomeEvent : public TimedEventQueue::Event {
606be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    AwesomeEvent(
616be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber            AwesomePlayer *player,
626be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber            void (AwesomePlayer::*method)())
6327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        : mPlayer(player),
646be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber          mMethod(method) {
6527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
6627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
6727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberprotected:
6827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    virtual ~AwesomeEvent() {}
6927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
7027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
716be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber        (mPlayer->*mMethod)();
7227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
7327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
7427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberprivate:
7527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    AwesomePlayer *mPlayer;
766be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    void (AwesomePlayer::*mMethod)();
7727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
7827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    AwesomeEvent(const AwesomeEvent &);
7927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    AwesomeEvent &operator=(const AwesomeEvent &);
8027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber};
8127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
821314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huberstruct AwesomeRemoteRenderer : public AwesomeRenderer {
831314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    AwesomeRemoteRenderer(const sp<IOMXRenderer> &target)
841314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber        : mTarget(target) {
851314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    }
861314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
87122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    virtual status_t initCheck() const {
88122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        return OK;
89122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    }
90122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
911314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    virtual void render(MediaBuffer *buffer) {
921314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber        void *id;
931314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber        if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) {
941314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber            mTarget->render((IOMX::buffer_id)id);
951314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber        }
961314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    }
971314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
981314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huberprivate:
991314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    sp<IOMXRenderer> mTarget;
1001314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
1011314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    AwesomeRemoteRenderer(const AwesomeRemoteRenderer &);
1021314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    AwesomeRemoteRenderer &operator=(const AwesomeRemoteRenderer &);
1031314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber};
1041314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
1051314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huberstruct AwesomeLocalRenderer : public AwesomeRenderer {
1061314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    AwesomeLocalRenderer(
1077b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber            bool previewOnly,
1084ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            const char *componentName,
1091314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber            OMX_COLOR_FORMATTYPE colorFormat,
1101314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber            const sp<ISurface> &surface,
1111314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber            size_t displayWidth, size_t displayHeight,
11231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            size_t decodedWidth, size_t decodedHeight,
11331dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            int32_t rotationDegrees)
114122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        : mInitCheck(NO_INIT),
115122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber          mTarget(NULL),
1164ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber          mLibHandle(NULL) {
117122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            mInitCheck = init(previewOnly, componentName,
1184ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber                 colorFormat, surface, displayWidth,
11931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                 displayHeight, decodedWidth, decodedHeight,
12031dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                 rotationDegrees);
1211314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    }
1221314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
123122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    virtual status_t initCheck() const {
124122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        return mInitCheck;
125122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    }
126122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
1271314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    virtual void render(MediaBuffer *buffer) {
1287b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        render((const uint8_t *)buffer->data() + buffer->range_offset(),
1297b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber               buffer->range_length());
1307b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    }
1317b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
1327b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    void render(const void *data, size_t size) {
1337b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        mTarget->render(data, size, NULL);
1341314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    }
1351314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
1361314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huberprotected:
1371314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    virtual ~AwesomeLocalRenderer() {
1381314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber        delete mTarget;
1391314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber        mTarget = NULL;
1404ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber
1414ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        if (mLibHandle) {
1424ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            dlclose(mLibHandle);
1434ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            mLibHandle = NULL;
1444ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        }
1451314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    }
1461314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
1471314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huberprivate:
148122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    status_t mInitCheck;
1494ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber    VideoRenderer *mTarget;
1504ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber    void *mLibHandle;
1514ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber
152122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    status_t init(
1537b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber            bool previewOnly,
1544ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            const char *componentName,
1554ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            OMX_COLOR_FORMATTYPE colorFormat,
1564ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            const sp<ISurface> &surface,
1574ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber            size_t displayWidth, size_t displayHeight,
15831dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            size_t decodedWidth, size_t decodedHeight,
15931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            int32_t rotationDegrees);
1601314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
1611314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    AwesomeLocalRenderer(const AwesomeLocalRenderer &);
1621314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber    AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
1631314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber};
1641314e73786afacb49ddbff7c3d0c1cf9d2c688c9Andreas Huber
165122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huberstatus_t AwesomeLocalRenderer::init(
1667b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        bool previewOnly,
1674ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        const char *componentName,
1684ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        OMX_COLOR_FORMATTYPE colorFormat,
1694ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        const sp<ISurface> &surface,
1704ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        size_t displayWidth, size_t displayHeight,
17131dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber        size_t decodedWidth, size_t decodedHeight,
17231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber        int32_t rotationDegrees) {
1737b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    if (!previewOnly) {
1747b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        // We will stick to the vanilla software-color-converting renderer
1757b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        // for "previewOnly" mode, to avoid unneccessarily switching overlays
1767b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        // more often than necessary.
1777b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
1787b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
1797b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
1807b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        if (mLibHandle) {
18131dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            typedef VideoRenderer *(*CreateRendererWithRotationFunc)(
18231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    const sp<ISurface> &surface,
18331dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    const char *componentName,
18431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    OMX_COLOR_FORMATTYPE colorFormat,
18531dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    size_t displayWidth, size_t displayHeight,
18631dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    size_t decodedWidth, size_t decodedHeight,
18731dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    int32_t rotationDegrees);
18831dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber
1897b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber            typedef VideoRenderer *(*CreateRendererFunc)(
1907b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    const sp<ISurface> &surface,
1917b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    const char *componentName,
1927b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    OMX_COLOR_FORMATTYPE colorFormat,
1937b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    size_t displayWidth, size_t displayHeight,
1947b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    size_t decodedWidth, size_t decodedHeight);
1957b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
19631dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            CreateRendererWithRotationFunc funcWithRotation =
19731dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                (CreateRendererWithRotationFunc)dlsym(
1987b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                        mLibHandle,
19931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                        "_Z26createRendererWithRotationRKN7android2spINS_8"
20031dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                        "ISurfaceEEEPKc20OMX_COLOR_FORMATTYPEjjjji");
2017b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
20231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            if (funcWithRotation) {
2037b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                mTarget =
20431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    (*funcWithRotation)(
20531dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            surface, componentName, colorFormat,
20631dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            displayWidth, displayHeight,
20731dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            decodedWidth, decodedHeight,
20831dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            rotationDegrees);
20931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            } else {
21031dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                if (rotationDegrees != 0) {
21131dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    LOGW("renderer does not support rotation.");
21231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                }
21331dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber
21431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                CreateRendererFunc func =
21531dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    (CreateRendererFunc)dlsym(
21631dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            mLibHandle,
21731dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
21831dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            "OMX_COLOR_FORMATTYPEjjjj");
21931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber
22031dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                if (func) {
22131dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    mTarget =
22231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                        (*func)(surface, componentName, colorFormat,
22331dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            displayWidth, displayHeight,
22431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                            decodedWidth, decodedHeight);
22531dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                }
2267b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber            }
2274ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber        }
2284ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber    }
2294ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber
230122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    if (mTarget != NULL) {
231122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        return OK;
2324ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber    }
233122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
234122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    mTarget = new SoftwareRenderer(
235122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            colorFormat, surface, displayWidth, displayHeight,
236122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            decodedWidth, decodedHeight, rotationDegrees);
237122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
238122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    return ((SoftwareRenderer *)mTarget)->initCheck();
2394ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber}
2404ab5a6fe78fafff9b409a6008f3ac51fecc5281dAndreas Huber
24127366fc9540cb642ee4856957dabffe7ddf1f901Andreas HuberAwesomePlayer::AwesomePlayer()
242406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    : mQueueStarted(false),
243406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber      mTimeSource(NULL),
2447b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber      mVideoRendererIsPreview(false),
24527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber      mAudioPlayer(NULL),
246ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber      mFlags(0),
24762f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber      mExtractorFlags(0),
24827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber      mLastVideoBuffer(NULL),
249ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber      mVideoBuffer(NULL),
250ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber      mSuspensionState(NULL) {
25127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    CHECK_EQ(mClient.connect(), OK);
25227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
25327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    DataSource::RegisterDefaultSniffers();
25427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
2556be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
25627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoEventPending = false;
2576be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
25827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mStreamDoneEventPending = false;
2596be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
260b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    mBufferingEventPending = false;
2616be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
2626be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mCheckAudioStatusEvent = new AwesomeEvent(
2636be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber            this, &AwesomePlayer::onCheckAudioStatus);
2646be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
26570d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    mAudioStatusEventPending = false;
26627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
26727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    reset();
26827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
26927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
27027366fc9540cb642ee4856957dabffe7ddf1f901Andreas HuberAwesomePlayer::~AwesomePlayer() {
271406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    if (mQueueStarted) {
272406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        mQueue.stop();
273406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    }
27427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
27527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    reset();
27627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
27727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mClient.disconnect();
27827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
27927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
280b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Hubervoid AwesomePlayer::cancelPlayerEvents(bool keepBufferingGoing) {
28127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mQueue.cancelEvent(mVideoEvent->eventID());
28227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoEventPending = false;
28327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mQueue.cancelEvent(mStreamDoneEvent->eventID());
28427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mStreamDoneEventPending = false;
28570d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
28670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    mAudioStatusEventPending = false;
287b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
288b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    if (!keepBufferingGoing) {
289b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber        mQueue.cancelEvent(mBufferingEvent->eventID());
290b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber        mBufferingEventPending = false;
291b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    }
29227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
29327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
294a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Hubervoid AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
29527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
29627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mListener = listener;
29727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
29827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
299433c9acaf7715eec080426af03cf1bf288076fe8Andreas Huberstatus_t AwesomePlayer::setDataSource(
300433c9acaf7715eec080426af03cf1bf288076fe8Andreas Huber        const char *uri, const KeyedVector<String8, String8> *headers) {
30127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
302ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    return setDataSource_l(uri, headers);
303ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber}
30427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
305ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huberstatus_t AwesomePlayer::setDataSource_l(
306ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        const char *uri, const KeyedVector<String8, String8> *headers) {
30727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    reset_l();
30827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
309ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mUri = uri;
310b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
311ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (headers) {
312ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        mUriHeaders = *headers;
313b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    }
314b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
315ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    // The actual work will be done during preparation in the call to
316ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    // ::finishSetDataSource_l to avoid blocking the calling thread in
317ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    // setDataSource for any significant time.
318b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
319ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    return OK;
32027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
32127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
32227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::setDataSource(
32327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        int fd, int64_t offset, int64_t length) {
32427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
32527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
32627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    reset_l();
32727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
328ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    sp<DataSource> dataSource = new FileSource(fd, offset, length);
32927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
330ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    status_t err = dataSource->initCheck();
33127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
33227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (err != OK) {
33327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return err;
33427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
33527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
336ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mFileSource = dataSource;
337ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
338ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    return setDataSource_l(dataSource);
339ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber}
340ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
341ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huberstatus_t AwesomePlayer::setDataSource_l(
342ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        const sp<DataSource> &dataSource) {
343ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
34427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
34527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (extractor == NULL) {
34627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return UNKNOWN_ERROR;
34727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
34827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
34927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return setDataSource_l(extractor);
35027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
35127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
35227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
3534deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    // Attempt to approximate overall stream bitrate by summing all
3544deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    // tracks' individual bitrates, if not all of them advertise bitrate,
3554deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    // we have to fail.
3564deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
3574deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    int64_t totalBitRate = 0;
3584deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
3594deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
3604deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
3614deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
3624deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        int32_t bitrate;
3634deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
3644deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber            totalBitRate = -1;
3654deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber            break;
3664deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        }
3674deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
3684deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        totalBitRate += bitrate;
3694deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    }
3704deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
3714deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    mBitrate = totalBitRate;
3724deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
3734deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    LOGV("mBitrate = %lld bits/sec", mBitrate);
3744deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
37527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    bool haveAudio = false;
37627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    bool haveVideo = false;
37727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
37827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
37927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
38027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        const char *mime;
38127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
38227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
38327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
3843ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber            setVideoSource(extractor->getTrack(i));
3853ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber            haveVideo = true;
38627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
3873ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber            setAudioSource(extractor->getTrack(i));
3883ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber            haveAudio = true;
3899fee0b2a02daa6fcf286ed930e45400dd3ba8dbaAndreas Huber
3901913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber            if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
3911913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                // Only do this for vorbis audio, none of the other audio
3921913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                // formats even support this ringtone specific hack and
3931913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                // retrieving the metadata on some extractors may turn out
3941913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                // to be very expensive.
3951913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                sp<MetaData> fileMeta = extractor->getMetaData();
3961913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                int32_t loop;
3971913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                if (fileMeta != NULL
3981913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                        && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
3991913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                    mFlags |= AUTO_LOOPING;
4001913c1aeabc1ff8d288c2be269fc50f010ad5f0fAndreas Huber                }
4019fee0b2a02daa6fcf286ed930e45400dd3ba8dbaAndreas Huber            }
40227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
40327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
40427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        if (haveAudio && haveVideo) {
40527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            break;
40627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
40727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
40827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
40962f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    if (!haveAudio && !haveVideo) {
41062f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber        return UNKNOWN_ERROR;
41162f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    }
41262f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber
41362f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    mExtractorFlags = extractor->flags();
41462f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber
41562f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    return OK;
41627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
41727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
41827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::reset() {
41927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
42027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    reset_l();
42127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
42227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
42327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::reset_l() {
424edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    if (mFlags & PREPARING) {
425edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        mFlags |= PREPARE_CANCELLED;
426edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        if (mConnectingDataSource != NULL) {
427edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            LOGI("interrupting the connection process");
428edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            mConnectingDataSource->disconnect();
429edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        }
430edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    }
431edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
432ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    while (mFlags & PREPARING) {
433ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        mPreparedCondition.wait(mLock);
434ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
435ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
43627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    cancelPlayerEvents();
43727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
4384d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    mCachedSource.clear();
4393ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mAudioTrack.clear();
4403ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mVideoTrack.clear();
4413ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber
442ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    // Shutdown audio first, so that the respone to the reset request
443ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    // appears to happen instantaneously as far as the user is concerned
444ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    // If we did this later, audio would continue playing while we
445ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    // shutdown the video-related resources and the player appear to
446ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    // not be as responsive to a reset request.
447edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    if (mAudioPlayer == NULL && mAudioSource != NULL) {
448edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        // If we had an audio player, it would have effectively
449edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        // taken possession of the audio source and stopped it when
450edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        // _it_ is stopped. Otherwise this is still our responsibility.
451edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        mAudioSource->stop();
452edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    }
453ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mAudioSource.clear();
454ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
455ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mTimeSource = NULL;
456ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
457ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    delete mAudioPlayer;
458ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mAudioPlayer = NULL;
459ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
4603522b5a579090f09ec4d304ee4b8fca6c755d39cAndreas Huber    mVideoRenderer.clear();
4613522b5a579090f09ec4d304ee4b8fca6c755d39cAndreas Huber
46227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mLastVideoBuffer) {
46327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mLastVideoBuffer->release();
46427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mLastVideoBuffer = NULL;
46527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
46627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
46727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mVideoBuffer) {
46827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mVideoBuffer->release();
46927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mVideoBuffer = NULL;
47027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
47127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
472e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber    if (mRTSPController != NULL) {
473e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber        mRTSPController->disconnect();
474e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber        mRTSPController.clear();
475e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber    }
476e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber
47757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mRTPPusher.clear();
47857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mRTCPPusher.clear();
47957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber    mRTPSession.clear();
4807a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
48127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mVideoSource != NULL) {
48227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mVideoSource->stop();
48398b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber
48498b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        // The following hack is necessary to ensure that the OMX
48598b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        // component is completely released by the time we may try
48698b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        // to instantiate it again.
48798b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        wp<MediaSource> tmp = mVideoSource;
48827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mVideoSource.clear();
48998b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        while (tmp.promote() != NULL) {
49098b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber            usleep(1000);
49198b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        }
49298b48dee325bd22ae73029cd6a42047036ed5ab1Andreas Huber        IPCThreadState::self()->flushCommands();
49327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
49427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
49527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mDurationUs = -1;
49627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mFlags = 0;
49762f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    mExtractorFlags = 0;
49827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoWidth = mVideoHeight = -1;
49927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mTimeSourceDeltaUs = 0;
50027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoTimeUs = 0;
50127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
50227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mSeeking = false;
5038e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber    mSeekNotificationSent = false;
50427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mSeekTimeUs = 0;
505b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
506ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mUri.setTo("");
507ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mUriHeaders.clear();
508ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
509ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mFileSource.clear();
510ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
511ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    delete mSuspensionState;
512ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mSuspensionState = NULL;
5134deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
5144deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    mBitrate = -1;
51527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
51627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
5176be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Hubervoid AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
518a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Huber    if (mListener != NULL) {
519a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Huber        sp<MediaPlayerBase> listener = mListener.promote();
520a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Huber
521a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Huber        if (listener != NULL) {
5226be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber            listener->sendEvent(msg, ext1, ext2);
523b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber        }
524b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    }
525b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber}
526b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
5274deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huberbool AwesomePlayer::getBitrate(int64_t *bitrate) {
5284deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    off_t size;
5294deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    if (mDurationUs >= 0 && mCachedSource != NULL
5304deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber            && mCachedSource->getSize(&size) == OK) {
5314deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
5324deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        return true;
5334deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    }
5344deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
5354deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    if (mBitrate >= 0) {
5364deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        *bitrate = mBitrate;
5374deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber        return true;
5384deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    }
5394deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
5404deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    *bitrate = 0;
5414deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
5424deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    return false;
5434deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber}
5444deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber
54587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber// Returns true iff cached duration is available/applicable.
54687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huberbool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
5474deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    int64_t bitrate;
54887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber
54987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mRTSPController != NULL) {
55087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        *durationUs = mRTSPController->getQueueDurationUs(eos);
55187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        return true;
5524deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber    } else if (mCachedSource != NULL && getBitrate(&bitrate)) {
55387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(eos);
55487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
55587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        return true;
55687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    }
55787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber
55887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    return false;
55987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber}
56087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber
561b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Hubervoid AwesomePlayer::onBufferingUpdate() {
562b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    Mutex::Autolock autoLock(mLock);
563c0178f10972304027c990a930d6c81060e772abeAndreas Huber    if (!mBufferingEventPending) {
564c0178f10972304027c990a930d6c81060e772abeAndreas Huber        return;
565c0178f10972304027c990a930d6c81060e772abeAndreas Huber    }
566b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    mBufferingEventPending = false;
567b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
56887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mCachedSource != NULL) {
5694d8f66bce32fbc8700b4ae5b2f6673a9cf1d20adAndreas Huber        bool eos;
57087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);
5714d8f66bce32fbc8700b4ae5b2f6673a9cf1d20adAndreas Huber
57287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        if (eos) {
57387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
57405f6787b887f0e731e7372ede0fb955e8939f703Andreas Huber            if (mFlags & PREPARING) {
57505f6787b887f0e731e7372ede0fb955e8939f703Andreas Huber                LOGV("cache has reached EOS, prepare is done.");
57605f6787b887f0e731e7372ede0fb955e8939f703Andreas Huber                finishAsyncPrepare_l();
57705f6787b887f0e731e7372ede0fb955e8939f703Andreas Huber            }
57887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        } else {
5794deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber            int64_t bitrate;
5804deb3eb534fea073c1b4afb032f4f1c643abb8e1Andreas Huber            if (getBitrate(&bitrate)) {
58187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                size_t cachedSize = mCachedSource->cachedSize();
58287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
5834d8f66bce32fbc8700b4ae5b2f6673a9cf1d20adAndreas Huber
58487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
58587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                if (percentage > 100) {
58687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    percentage = 100;
58787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                }
5884d8f66bce32fbc8700b4ae5b2f6673a9cf1d20adAndreas Huber
58987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
59087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            } else {
59187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                // We don't know the bitrate of the stream, use absolute size
59287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                // limits to maintain the cache.
59387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber
59487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                if ((mFlags & PLAYING) && !eos
59587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
59687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    LOGI("cache is running low (< %d) , pausing.",
59787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                         kLowWaterMarkBytes);
59887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    mFlags |= CACHE_UNDERRUN;
59987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    pause_l();
60087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
60187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
60287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    if (mFlags & CACHE_UNDERRUN) {
60387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        LOGI("cache has filled up (> %d), resuming.",
60487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                             kHighWaterMarkBytes);
60587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        mFlags &= ~CACHE_UNDERRUN;
60687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        play_l();
60787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
60887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    } else if (mFlags & PREPARING) {
60987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        LOGV("cache has filled up (> %d), prepare is done",
61087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                             kHighWaterMarkBytes);
61187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                        finishAsyncPrepare_l();
61287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                    }
61387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                }
61487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            }
61587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        }
616252573cb821259e883843630e6d69317cfb76850Andreas Huber    }
617252573cb821259e883843630e6d69317cfb76850Andreas Huber
61887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    int64_t cachedDurationUs;
619c23296ef2d168f29bcfc3c93d33f78e1c393177aAndreas Huber    bool eos;
62087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
62187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        if ((mFlags & PLAYING) && !eos
62287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                && (cachedDurationUs < kLowWaterMarkUs)) {
62387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            LOGI("cache is running low (%.2f secs) , pausing.",
62487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                 cachedDurationUs / 1E6);
62587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            mFlags |= CACHE_UNDERRUN;
62687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            pause_l();
62787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
62887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
62987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            if (mFlags & CACHE_UNDERRUN) {
63087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                LOGI("cache has filled up (%.2f secs), resuming.",
63187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                     cachedDurationUs / 1E6);
63287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                mFlags &= ~CACHE_UNDERRUN;
63387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                play_l();
63487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
63587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            } else if (mFlags & PREPARING) {
63687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                LOGV("cache has filled up (%.2f secs), prepare is done",
63787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                     cachedDurationUs / 1E6);
63887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber                finishAsyncPrepare_l();
639c23296ef2d168f29bcfc3c93d33f78e1c393177aAndreas Huber            }
640c23296ef2d168f29bcfc3c93d33f78e1c393177aAndreas Huber        }
6414d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    }
6424d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
6434d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    postBufferingEvent_l();
644a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Huber}
645a3f4384ce829132d7ffcd3d284d641e73a8896a6Andreas Huber
6464c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Hubervoid AwesomePlayer::partial_reset_l() {
6474c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    // Only reset the video renderer and shut down the video decoder.
6484c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    // Then instantiate a new video decoder and resume video playback.
6494c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6504c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    mVideoRenderer.clear();
6514c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6524c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    if (mLastVideoBuffer) {
6534c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        mLastVideoBuffer->release();
6544c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        mLastVideoBuffer = NULL;
6554c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    }
6564c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6574c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    if (mVideoBuffer) {
6584c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        mVideoBuffer->release();
6594c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        mVideoBuffer = NULL;
6604c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    }
6614c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6624c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    {
6634c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        mVideoSource->stop();
6644c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6654c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // The following hack is necessary to ensure that the OMX
6664c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // component is completely released by the time we may try
6674c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // to instantiate it again.
6684c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        wp<MediaSource> tmp = mVideoSource;
6694c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        mVideoSource.clear();
6704c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        while (tmp.promote() != NULL) {
6714c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber            usleep(1000);
6724c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        }
6734c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        IPCThreadState::self()->flushCommands();
6744c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    }
6754c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6764c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    CHECK_EQ(OK, initVideoDecoder(OMXCodec::kIgnoreCodecSpecificData));
6774c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber}
6784c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
67927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::onStreamDone() {
68027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    // Posted whenever any stream finishes playing.
68127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
68227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
683c0178f10972304027c990a930d6c81060e772abeAndreas Huber    if (!mStreamDoneEventPending) {
684c0178f10972304027c990a930d6c81060e772abeAndreas Huber        return;
685c0178f10972304027c990a930d6c81060e772abeAndreas Huber    }
68627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mStreamDoneEventPending = false;
68727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
6884c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    if (mStreamDoneStatus == INFO_DISCONTINUITY) {
6894c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // This special status is returned because an http live stream's
6904c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // video stream switched to a different bandwidth at this point
6914c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // and future data may have been encoded using different parameters.
6924c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // This requires us to shutdown the video decoder and reinstantiate
6934c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        // a fresh one.
6944c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6954c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        LOGV("INFO_DISCONTINUITY");
6964c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6974c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        CHECK(mVideoSource != NULL);
6984c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber
6994c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        partial_reset_l();
7004c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        postVideoEvent_l();
7014c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber        return;
7024c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huber    } else if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
703971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
704971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
705971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        notifyListener_l(
706971305d4af1c4058596c5a3feac301585682d15cAndreas Huber                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
707971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
708c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber        pause_l(true /* at eos */);
709971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
710971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        mFlags |= AT_EOS;
711971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        return;
712971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    }
713971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
714971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    const bool allDone =
715971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
716971305d4af1c4058596c5a3feac301585682d15cAndreas Huber            && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
717971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
718971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    if (!allDone) {
719971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        return;
720971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    }
721971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
7229fee0b2a02daa6fcf286ed930e45400dd3ba8dbaAndreas Huber    if (mFlags & (LOOPING | AUTO_LOOPING)) {
72327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        seekTo_l(0);
72427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
7257085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber        if (mVideoSource != NULL) {
72627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            postVideoEvent_l();
72727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
72827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    } else {
729971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        LOGV("MEDIA_PLAYBACK_COMPLETE");
730971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
73127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
732c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber        pause_l(true /* at eos */);
733406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber
734406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        mFlags |= AT_EOS;
73527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
73627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
73727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
73827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::play() {
73927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
7404d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
7414d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    mFlags &= ~CACHE_UNDERRUN;
7424d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
743ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    return play_l();
744ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber}
74527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
746ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huberstatus_t AwesomePlayer::play_l() {
74727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mFlags & PLAYING) {
74827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return OK;
74927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
75027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
751ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (!(mFlags & PREPARED)) {
752ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        status_t err = prepare_l();
753ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
754ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        if (err != OK) {
755ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber            return err;
756ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        }
757ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
758ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
75927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mFlags |= PLAYING;
76027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mFlags |= FIRST_FRAME;
76127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
762c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber    bool deferredAudioSeek = false;
763c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber
76427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mAudioSource != NULL) {
76527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        if (mAudioPlayer == NULL) {
76627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            if (mAudioSink != NULL) {
7672b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber                mAudioPlayer = new AudioPlayer(mAudioSink, this);
76827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                mAudioPlayer->setSource(mAudioSource);
769dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber
770dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber                // We've already started the MediaSource in order to enable
771dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber                // the prefetcher to read its data.
772dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber                status_t err = mAudioPlayer->start(
773dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber                        true /* sourceAlreadyStarted */);
77462eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber
77562eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber                if (err != OK) {
77662eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber                    delete mAudioPlayer;
77762eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber                    mAudioPlayer = NULL;
77862eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber
77962eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber                    mFlags &= ~(PLAYING | FIRST_FRAME);
78062eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber
78162eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber                    return err;
78262eac008504fefd05fa53bc74f7e001bf0a51975Andreas Huber                }
78327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
78427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                mTimeSource = mAudioPlayer;
78527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
786c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber                deferredAudioSeek = true;
78770d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber
78870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber                mWatchForAudioSeekComplete = false;
78970d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber                mWatchForAudioEOS = true;
79027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            }
79127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        } else {
79227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            mAudioPlayer->resume();
79327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
79427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
79527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
79627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mTimeSource == NULL && mAudioPlayer == NULL) {
797971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        mTimeSource = &mSystemTimeSource;
79827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
79927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
80027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mVideoSource != NULL) {
8017085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber        // Kick off video playback
8027085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber        postVideoEvent_l();
80327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
80427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
805c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber    if (deferredAudioSeek) {
806c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber        // If there was a seek request while we were paused
807c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber        // and we're just starting up again, honor the request now.
808c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber        seekAudioIfNecessary_l();
809c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber    }
810c1d5c921d62475fb0b9eec46ce1a9278c96fd9e2Andreas Huber
811406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    if (mFlags & AT_EOS) {
812406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        // Legacy behaviour, if a stream finishes playing and then
813406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        // is started again, we play from the start...
814406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        seekTo_l(0);
815406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    }
816406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber
81727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
81827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
81927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
820122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huberstatus_t AwesomePlayer::initRenderer_l() {
821122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    if (mISurface == NULL) {
822122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        return OK;
823122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    }
82431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber
825122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    sp<MetaData> meta = mVideoSource->getFormat();
826a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber
827122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    int32_t format;
828122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    const char *component;
829122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    int32_t decodedWidth, decodedHeight;
830122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &format));
831122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    CHECK(meta->findCString(kKeyDecoderComponent, &component));
832122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
833122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
834a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber
835122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    int32_t rotationDegrees;
836122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    if (!mVideoTrack->getFormat()->findInt32(
837122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                kKeyRotation, &rotationDegrees)) {
838122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        rotationDegrees = 0;
83927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
840122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
841122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    mVideoRenderer.clear();
842122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
843122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    // Must ensure that mVideoRenderer's destructor is actually executed
844122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    // before creating a new one.
845122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    IPCThreadState::self()->flushCommands();
846122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
847122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    if (!strncmp("OMX.", component, 4)) {
848122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        // Our OMX codecs allocate buffers on the media_server side
849122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        // therefore they require a remote IOMXRenderer that knows how
850122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        // to display them.
851122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
852122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        sp<IOMXRenderer> native =
853122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            mClient.interface()->createRenderer(
854122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                    mISurface, component,
855122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                    (OMX_COLOR_FORMATTYPE)format,
856122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                    decodedWidth, decodedHeight,
857122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                    mVideoWidth, mVideoHeight,
858122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                    rotationDegrees);
859122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
860122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        if (native == NULL) {
861122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            return NO_INIT;
862122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        }
863122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
864122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        mVideoRenderer = new AwesomeRemoteRenderer(native);
865122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    } else {
866122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        // Other decoders are instantiated locally and as a consequence
867122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        // allocate their buffers in local address space.
868122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        mVideoRenderer = new AwesomeLocalRenderer(
869122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            false,  // previewOnly
870122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            component,
871122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            (OMX_COLOR_FORMATTYPE)format,
872122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            mISurface,
873122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            mVideoWidth, mVideoHeight,
874122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            decodedWidth, decodedHeight, rotationDegrees);
875122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    }
876122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
877122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber    return mVideoRenderer->initCheck();
87827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
87927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
88027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::pause() {
88127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
8824d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
8834d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    mFlags &= ~CACHE_UNDERRUN;
8844d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
88527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return pause_l();
88627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
88727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
888c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huberstatus_t AwesomePlayer::pause_l(bool at_eos) {
88927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (!(mFlags & PLAYING)) {
89027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return OK;
89127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
89227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
893b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    cancelPlayerEvents(true /* keepBufferingGoing */);
89427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
89527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mAudioPlayer != NULL) {
896c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber        if (at_eos) {
897c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber            // If we played the audio stream to completion we
898c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber            // want to make sure that all samples remaining in the audio
899c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber            // track's queue are played out.
900c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber            mAudioPlayer->pause(true /* playPendingSamples */);
901c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber        } else {
902c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber            mAudioPlayer->pause();
903c743f4506f88a14189449c719a6ec1cfe5f0f812Andreas Huber        }
90427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
90527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
90627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mFlags &= ~PLAYING;
90727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
90827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
90927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
91027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
91127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberbool AwesomePlayer::isPlaying() const {
9124d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
91327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
91427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
91527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::setISurface(const sp<ISurface> &isurface) {
91627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
91727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
91827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mISurface = isurface;
91927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
92027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
92127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::setAudioSink(
92227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        const sp<MediaPlayerBase::AudioSink> &audioSink) {
92327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
92427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
92527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mAudioSink = audioSink;
92627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
92727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
92827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::setLooping(bool shouldLoop) {
92927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
93027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
93127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mFlags = mFlags & ~LOOPING;
93227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
93327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (shouldLoop) {
93427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mFlags |= LOOPING;
93527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
93627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
93727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
93827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
93927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
94027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::getDuration(int64_t *durationUs) {
941252573cb821259e883843630e6d69317cfb76850Andreas Huber    Mutex::Autolock autoLock(mMiscStateLock);
94227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
94327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mDurationUs < 0) {
94427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return UNKNOWN_ERROR;
94527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
94627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
94727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    *durationUs = mDurationUs;
94827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
94927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
95027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
95127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
95227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::getPosition(int64_t *positionUs) {
953eeb97d91b97f1fc0b26815f098515e9c06d219b8Andreas Huber    if (mRTSPController != NULL) {
954eeb97d91b97f1fc0b26815f098515e9c06d219b8Andreas Huber        *positionUs = mRTSPController->getNormalPlayTimeUs();
955eeb97d91b97f1fc0b26815f098515e9c06d219b8Andreas Huber    }
956eeb97d91b97f1fc0b26815f098515e9c06d219b8Andreas Huber    else if (mSeeking) {
957ddb709c45e6b1a2127db7f34f6a4f1c09402d76bAndreas Huber        *positionUs = mSeekTimeUs;
958ddb709c45e6b1a2127db7f34f6a4f1c09402d76bAndreas Huber    } else if (mVideoSource != NULL) {
959252573cb821259e883843630e6d69317cfb76850Andreas Huber        Mutex::Autolock autoLock(mMiscStateLock);
96027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        *positionUs = mVideoTimeUs;
96127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    } else if (mAudioPlayer != NULL) {
96227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        *positionUs = mAudioPlayer->getMediaTimeUs();
96327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    } else {
96427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        *positionUs = 0;
96527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
96627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
96727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
96827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
96927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
97027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::seekTo(int64_t timeUs) {
97110b9b3f3fe47cea0833fe2c7d5ed08a1185f9006Andreas Huber    if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
97262f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber        Mutex::Autolock autoLock(mLock);
97362f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber        return seekTo_l(timeUs);
97462f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    }
97562f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber
97662f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    return OK;
97727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
97827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
9790c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber// static
9800c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Hubervoid AwesomePlayer::OnRTSPSeekDoneWrapper(void *cookie) {
9810c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber    static_cast<AwesomePlayer *>(cookie)->onRTSPSeekDone();
9820c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber}
9830c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber
9840c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Hubervoid AwesomePlayer::onRTSPSeekDone() {
9850c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber    notifyListener_l(MEDIA_SEEK_COMPLETE);
9860c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber    mSeekNotificationSent = true;
9870c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber}
9880c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber
98927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::seekTo_l(int64_t timeUs) {
990e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber    if (mRTSPController != NULL) {
9910c46b69f612da61ed39b32823d2d6baf2e8215e9Andreas Huber        mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this);
992e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber        return OK;
993e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber    }
994e0dd7d396051942ccce0429d7a1fe968d63ac3f7Andreas Huber
9954d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    if (mFlags & CACHE_UNDERRUN) {
9964d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        mFlags &= ~CACHE_UNDERRUN;
9974d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        play_l();
9984d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber    }
9994d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
100027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mSeeking = true;
10018e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber    mSeekNotificationSent = false;
100227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mSeekTimeUs = timeUs;
1003971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
100427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
100527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    seekAudioIfNecessary_l();
100627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
10078e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber    if (!(mFlags & PLAYING)) {
10088e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber        LOGV("seeking while paused, sending SEEK_COMPLETE notification"
10098e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber             " immediately.");
10108e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber
10118e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber        notifyListener_l(MEDIA_SEEK_COMPLETE);
10128e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber        mSeekNotificationSent = true;
10138e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber    }
10148e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber
101527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
101627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
101727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
101827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::seekAudioIfNecessary_l() {
10197085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber    if (mSeeking && mVideoSource == NULL && mAudioPlayer != NULL) {
102027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mAudioPlayer->seekTo(mSeekTimeUs);
102127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
102270d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber        mWatchForAudioSeekComplete = true;
102370d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber        mWatchForAudioEOS = true;
10248e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber        mSeekNotificationSent = false;
102527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
102627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
102727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
102827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huberstatus_t AwesomePlayer::getVideoDimensions(
102927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        int32_t *width, int32_t *height) const {
103027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
103127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
103227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mVideoWidth < 0 || mVideoHeight < 0) {
103327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return UNKNOWN_ERROR;
103427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
103527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
103627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    *width = mVideoWidth;
103727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    *height = mVideoHeight;
103827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
103927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return OK;
104027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
104127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
10423ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Hubervoid AwesomePlayer::setAudioSource(sp<MediaSource> source) {
10433ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    CHECK(source != NULL);
104427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
10453ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mAudioTrack = source;
10463ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber}
10473ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber
10483ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huberstatus_t AwesomePlayer::initAudioDecoder() {
10493ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    sp<MetaData> meta = mAudioTrack->getFormat();
1050c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber
1051c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber    const char *mime;
1052c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
1053c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber
1054c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
10553ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber        mAudioSource = mAudioTrack;
1056c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber    } else {
1057c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber        mAudioSource = OMXCodec::Create(
10583ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber                mClient.interface(), mAudioTrack->getFormat(),
1059c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber                false, // createEncoder
10603ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber                mAudioTrack);
1061c79827a76f91fd36c2f3d598dc7288f6abb86745Andreas Huber    }
106227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
106327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mAudioSource != NULL) {
106427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        int64_t durationUs;
10653ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber        if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1066252573cb821259e883843630e6d69317cfb76850Andreas Huber            Mutex::Autolock autoLock(mMiscStateLock);
106727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            if (mDurationUs < 0 || durationUs > mDurationUs) {
106827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                mDurationUs = durationUs;
106927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            }
107027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
107127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
10723c78a1b58957e31d2991fb6a609abecbb1987b3bAndreas Huber        status_t err = mAudioSource->start();
10733c78a1b58957e31d2991fb6a609abecbb1987b3bAndreas Huber
10743c78a1b58957e31d2991fb6a609abecbb1987b3bAndreas Huber        if (err != OK) {
10753c78a1b58957e31d2991fb6a609abecbb1987b3bAndreas Huber            mAudioSource.clear();
10763c78a1b58957e31d2991fb6a609abecbb1987b3bAndreas Huber            return err;
10773c78a1b58957e31d2991fb6a609abecbb1987b3bAndreas Huber        }
1078d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
1079d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber        // For legacy reasons we're simply going to ignore the absence
1080d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber        // of an audio decoder for QCELP instead of aborting playback
1081d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber        // altogether.
1082d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber        return OK;
1083d0332ad8d212d87fbf909fc780e6378b4d2c20c1Andreas Huber    }
1084dc9927d4641066fc966c9c69856167b8410abf90Andreas Huber
108527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
108627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
108727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
10883ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Hubervoid AwesomePlayer::setVideoSource(sp<MediaSource> source) {
10893ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    CHECK(source != NULL);
109027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
10913ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mVideoTrack = source;
10923ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber}
10933ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber
10944c19bf9833f59f58a9aaea566f0eb98a7fb7e2eaAndreas Huberstatus_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
109527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoSource = OMXCodec::Create(
10963ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber            mClient.interface(), mVideoTrack->getFormat(),
109727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            false, // createEncoder
109857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            mVideoTrack,
109957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            NULL, flags);
110027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
110127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mVideoSource != NULL) {
110227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        int64_t durationUs;
11033ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1104252573cb821259e883843630e6d69317cfb76850Andreas Huber            Mutex::Autolock autoLock(mMiscStateLock);
110527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            if (mDurationUs < 0 || durationUs > mDurationUs) {
110627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                mDurationUs = durationUs;
110727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            }
110827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
110927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
11103ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber        CHECK(mVideoTrack->getFormat()->findInt32(kKeyWidth, &mVideoWidth));
11113ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber        CHECK(mVideoTrack->getFormat()->findInt32(kKeyHeight, &mVideoHeight));
111227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
11131919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber        status_t err = mVideoSource->start();
11141919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber
11151919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber        if (err != OK) {
11161919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber            mVideoSource.clear();
11171919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber            return err;
11181919e5af3d8eb8bcf08e50efae2e79eaf065cf6bAndreas Huber        }
111927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
112027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
112127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
112227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
112327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
11244d450a86572e549f845d335ab98eac0fd13d2c85Andreas Hubervoid AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
11254d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    if (!mSeeking) {
11264d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        return;
11274d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    }
11284d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber
11294d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    if (mAudioPlayer != NULL) {
1130f0f1ceeb517ff226532a407da6d55602f195e5b5Andreas Huber        LOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
11314d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber
11324d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        // If we don't have a video time, seek audio to the originally
11334d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        // requested seek time instead.
11344d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber
11354d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
11364d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        mAudioPlayer->resume();
11374d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        mWatchForAudioSeekComplete = true;
11384d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        mWatchForAudioEOS = true;
11394d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    } else if (!mSeekNotificationSent) {
11404d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        // If we're playing video only, report seek complete now,
11414d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        // otherwise audio player will notify us later.
11424d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber        notifyListener_l(MEDIA_SEEK_COMPLETE);
11434d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    }
11444d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber
11454d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    mFlags |= FIRST_FRAME;
11464d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    mSeeking = false;
11474d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    mSeekNotificationSent = false;
11484d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber}
11494d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber
11506be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Hubervoid AwesomePlayer::onVideoEvent() {
115127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    Mutex::Autolock autoLock(mLock);
1152ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    if (!mVideoEventPending) {
1153ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        // The event has been cancelled in reset_l() but had already
1154ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        // been scheduled for execution at that time.
1155ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        return;
1156ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
115727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoEventPending = false;
115827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
115927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mSeeking) {
116027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        if (mLastVideoBuffer) {
116127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            mLastVideoBuffer->release();
116227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            mLastVideoBuffer = NULL;
116327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
116427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
116527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        if (mVideoBuffer) {
116627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            mVideoBuffer->release();
116727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            mVideoBuffer = NULL;
116827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
11694d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
11704d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        if (mCachedSource != NULL && mAudioSource != NULL) {
11714d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // We're going to seek the video source first, followed by
11724d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // the audio source.
11734d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // In order to avoid jumps in the DataSource offset caused by
11744d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // the audio codec prefetching data from the old locations
11754d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // while the video codec is already reading data from the new
11764d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // locations, we'll "pause" the audio source, causing it to
11774d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            // stop reading input data until a subsequent seek.
11784d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
11794d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            if (mAudioPlayer != NULL) {
11804d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber                mAudioPlayer->pause();
11814d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            }
11824d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber            mAudioSource->pause();
11834d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        }
118427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
118527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
118627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (!mVideoBuffer) {
118727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        MediaSource::ReadOptions options;
118827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        if (mSeeking) {
118927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
119027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
11916624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber            options.setSeekTo(
11926624c9fd0bc5e3858a22a04c05b5059445c1c367Andreas Huber                    mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
119327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
119427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        for (;;) {
119527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            status_t err = mVideoSource->read(&mVideoBuffer, &options);
1196b1f5ee41e9326dff132ad59de169cb3e79930f07Andreas Huber            options.clearSeekTo();
119727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
119827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            if (err != OK) {
119927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                CHECK_EQ(mVideoBuffer, NULL);
120027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
120127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                if (err == INFO_FORMAT_CHANGED) {
120227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                    LOGV("VideoSource signalled format change.");
120327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
12047085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber                    if (mVideoRenderer != NULL) {
12057b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                        mVideoRendererIsPreview = false;
1206122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                        err = initRenderer_l();
1207122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
1208122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                        if (err == OK) {
1209122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                            continue;
1210122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                        }
1211122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
1212122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber                        // fall through
1213da1b16ad41f7a4abf2531f86e1ba6053b588dae8James Dong                    } else {
1214da1b16ad41f7a4abf2531f86e1ba6053b588dae8James Dong                        continue;
12157085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber                    }
121627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                }
121727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
12184d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                // So video playback is complete, but we may still have
12194d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                // a seek request pending that needs to be applied
12204d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                // to the audio track.
12214d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                if (mSeeking) {
12224d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                    LOGV("video stream ended while seeking!");
12234d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                }
12244d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber                finishSeekIfNecessary(-1);
12254d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber
1226971305d4af1c4058596c5a3feac301585682d15cAndreas Huber                mFlags |= VIDEO_AT_EOS;
1227d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                postStreamDoneEvent_l(err);
122827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber                return;
122927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            }
123027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1231a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber            if (mVideoBuffer->range_length() == 0) {
12326ddcf01a9033ee7ff4230efd117d7bcc8b5b3cc1Andreas Huber                // Some decoders, notably the PV AVC software decoder
12336ddcf01a9033ee7ff4230efd117d7bcc8b5b3cc1Andreas Huber                // return spurious empty buffers that we just want to ignore.
12346ddcf01a9033ee7ff4230efd117d7bcc8b5b3cc1Andreas Huber
1235a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber                mVideoBuffer->release();
1236a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber                mVideoBuffer = NULL;
1237a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber                continue;
1238a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber            }
1239a67d538881413c4b73e7c9854e293b71b407e9c2Andreas Huber
124027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber            break;
124127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        }
124227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
124327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
124427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    int64_t timeUs;
124527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
124627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1247252573cb821259e883843630e6d69317cfb76850Andreas Huber    {
1248252573cb821259e883843630e6d69317cfb76850Andreas Huber        Mutex::Autolock autoLock(mMiscStateLock);
1249252573cb821259e883843630e6d69317cfb76850Andreas Huber        mVideoTimeUs = timeUs;
1250252573cb821259e883843630e6d69317cfb76850Andreas Huber    }
125127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
12520fb258d6c360c1fca42c594527792314e358ce93Andreas Huber    bool wasSeeking = mSeeking;
12534d450a86572e549f845d335ab98eac0fd13d2c85Andreas Huber    finishSeekIfNecessary(timeUs);
125427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1255971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    TimeSource *ts = (mFlags & AUDIO_AT_EOS) ? &mSystemTimeSource : mTimeSource;
1256971305d4af1c4058596c5a3feac301585682d15cAndreas Huber
125727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mFlags & FIRST_FRAME) {
125827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mFlags &= ~FIRST_FRAME;
125927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1260971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
126127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
126227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
126327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    int64_t realTimeUs, mediaTimeUs;
1264971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
126527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
126627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
126727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
126827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1269971305d4af1c4058596c5a3feac301585682d15cAndreas Huber    int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
127027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
127127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    int64_t latenessUs = nowUs - timeUs;
127227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
12730fb258d6c360c1fca42c594527792314e358ce93Andreas Huber    if (wasSeeking) {
12740fb258d6c360c1fca42c594527792314e358ce93Andreas Huber        // Let's display the first frame after seeking right away.
12750fb258d6c360c1fca42c594527792314e358ce93Andreas Huber        latenessUs = 0;
12760fb258d6c360c1fca42c594527792314e358ce93Andreas Huber    }
12770fb258d6c360c1fca42c594527792314e358ce93Andreas Huber
1278f88f84414ae7baead03497f1d650ad8ea2f87688Andreas Huber    if (mRTPSession != NULL) {
1279f88f84414ae7baead03497f1d650ad8ea2f87688Andreas Huber        // We'll completely ignore timestamps for gtalk videochat
1280f88f84414ae7baead03497f1d650ad8ea2f87688Andreas Huber        // and we'll play incoming video as fast as we get it.
1281f88f84414ae7baead03497f1d650ad8ea2f87688Andreas Huber        latenessUs = 0;
1282f88f84414ae7baead03497f1d650ad8ea2f87688Andreas Huber    }
1283f88f84414ae7baead03497f1d650ad8ea2f87688Andreas Huber
128424b0a95de7d1e8b57aa2cda1a04a0e40e80a4372Andreas Huber    if (latenessUs > 40000) {
128524b0a95de7d1e8b57aa2cda1a04a0e40e80a4372Andreas Huber        // We're more than 40ms late.
12864a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber        LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);
128727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
128827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mVideoBuffer->release();
128927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mVideoBuffer = NULL;
129027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
129127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        postVideoEvent_l();
129227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return;
129327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
129427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
129527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (latenessUs < -10000) {
129627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        // We're more than 10ms early.
129727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
129827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        postVideoEvent_l(10000);
129927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return;
130027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
130127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
13027b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
13037b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        mVideoRendererIsPreview = false;
13047b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
1305122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        status_t err = initRenderer_l();
1306122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
1307122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        if (err != OK) {
1308122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            finishSeekIfNecessary(-1);
1309122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber
1310122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            mFlags |= VIDEO_AT_EOS;
1311122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            postStreamDoneEvent_l(err);
1312122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber            return;
1313122a9ccbcdcdaf00a349813555d28d86709a6ed9Andreas Huber        }
13147085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber    }
13157085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber
13167085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber    if (mVideoRenderer != NULL) {
13177085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber        mVideoRenderer->render(mVideoBuffer);
13187085b684c6e1dcd87686fd32d72498ffabd22677Andreas Huber    }
131927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
132027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mLastVideoBuffer) {
132127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mLastVideoBuffer->release();
132227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        mLastVideoBuffer = NULL;
132327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
132427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mLastVideoBuffer = mVideoBuffer;
132527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoBuffer = NULL;
132627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
132727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    postVideoEvent_l();
132827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
132927366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
133027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Hubervoid AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
133127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mVideoEventPending) {
133227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return;
133327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
133427366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
133527366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mVideoEventPending = true;
133627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
133727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
133827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1339d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Hubervoid AwesomePlayer::postStreamDoneEvent_l(status_t status) {
134027366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    if (mStreamDoneEventPending) {
134127366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber        return;
134227366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    }
134327366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mStreamDoneEventPending = true;
1344d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber
1345d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber    mStreamDoneStatus = status;
134627366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber    mQueue.postEvent(mStreamDoneEvent);
134727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}
134827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1349b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Hubervoid AwesomePlayer::postBufferingEvent_l() {
1350b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    if (mBufferingEventPending) {
1351b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber        return;
1352b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    }
1353b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    mBufferingEventPending = true;
1354b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber    mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
1355b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber}
1356b9e63830c69231c53dc23a5e29f5b58a1d9d3668Andreas Huber
135770d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Hubervoid AwesomePlayer::postCheckAudioStatusEvent_l() {
135870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    if (mAudioStatusEventPending) {
135970d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber        return;
136070d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    }
136170d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    mAudioStatusEventPending = true;
13622b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber    mQueue.postEvent(mCheckAudioStatusEvent);
136370d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber}
136470d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber
136570d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Hubervoid AwesomePlayer::onCheckAudioStatus() {
136670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    Mutex::Autolock autoLock(mLock);
1367c0178f10972304027c990a930d6c81060e772abeAndreas Huber    if (!mAudioStatusEventPending) {
1368c0178f10972304027c990a930d6c81060e772abeAndreas Huber        // Event was dispatched and while we were blocking on the mutex,
1369c0178f10972304027c990a930d6c81060e772abeAndreas Huber        // has already been cancelled.
1370c0178f10972304027c990a930d6c81060e772abeAndreas Huber        return;
1371c0178f10972304027c990a930d6c81060e772abeAndreas Huber    }
1372c0178f10972304027c990a930d6c81060e772abeAndreas Huber
137370d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    mAudioStatusEventPending = false;
137470d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber
137570d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
137670d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber        mWatchForAudioSeekComplete = false;
13778e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber
13788e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber        if (!mSeekNotificationSent) {
13798e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber            notifyListener_l(MEDIA_SEEK_COMPLETE);
13808e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber            mSeekNotificationSent = true;
13818e2b941e7bc44dbe392aa220d28c2182aa023035Andreas Huber        }
1382ddb709c45e6b1a2127db7f34f6a4f1c09402d76bAndreas Huber
1383ddb709c45e6b1a2127db7f34f6a4f1c09402d76bAndreas Huber        mSeeking = false;
138470d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    }
138570d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber
1386d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber    status_t finalStatus;
1387d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber    if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
138870d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber        mWatchForAudioEOS = false;
1389971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        mFlags |= AUDIO_AT_EOS;
1390971305d4af1c4058596c5a3feac301585682d15cAndreas Huber        mFlags |= FIRST_FRAME;
1391d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber        postStreamDoneEvent_l(finalStatus);
139270d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber    }
139370d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber}
139470d10c0156f5d2d1c639d0ebe62de8ec950d4306Andreas Huber
13956be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huberstatus_t AwesomePlayer::prepare() {
13966be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    Mutex::Autolock autoLock(mLock);
1397ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    return prepare_l();
1398ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber}
13996be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1400ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huberstatus_t AwesomePlayer::prepare_l() {
1401ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (mFlags & PREPARED) {
1402ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        return OK;
1403ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
1404ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1405ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (mFlags & PREPARING) {
1406ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        return UNKNOWN_ERROR;
1407ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
1408ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1409ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mIsAsyncPrepare = false;
14106be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    status_t err = prepareAsync_l();
14116be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
14126be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    if (err != OK) {
14136be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber        return err;
14146be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    }
14156be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1416ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    while (mFlags & PREPARING) {
14176be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber        mPreparedCondition.wait(mLock);
14186be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    }
14196be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1420ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    return mPrepareResult;
14216be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber}
14226be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
14236be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huberstatus_t AwesomePlayer::prepareAsync() {
14246be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    Mutex::Autolock autoLock(mLock);
1425ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1426ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (mFlags & PREPARING) {
1427ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        return UNKNOWN_ERROR;  // async prepare already pending
1428ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
1429ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1430ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mIsAsyncPrepare = true;
14316be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    return prepareAsync_l();
14326be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber}
14336be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
14346be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huberstatus_t AwesomePlayer::prepareAsync_l() {
1435ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (mFlags & PREPARING) {
1436ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        return UNKNOWN_ERROR;  // async prepare already pending
14376be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    }
14386be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1439406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    if (!mQueueStarted) {
1440406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        mQueue.start();
1441406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber        mQueueStarted = true;
1442406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber    }
1443406a18b5b3d53466a3e03b66413ff3a50243a6a8Andreas Huber
1444ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mFlags |= PREPARING;
14456be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mAsyncPrepareEvent = new AwesomeEvent(
14466be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber            this, &AwesomePlayer::onPrepareAsyncEvent);
14476be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
14486be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mQueue.postEvent(mAsyncPrepareEvent);
14496be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
14506be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    return OK;
14516be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber}
14526be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1453ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huberstatus_t AwesomePlayer::finishSetDataSource_l() {
1454edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    sp<DataSource> dataSource;
1455edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
1456edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    if (!strncasecmp("http://", mUri.string(), 7)) {
14574d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        mConnectingDataSource = new NuHTTPDataSource;
1458edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
1459edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        mLock.unlock();
14603a53dc5ad9c2fa808b87195cfde9f3a065d6fa5bAndreas Huber        status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
1461edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        mLock.lock();
1462edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
1463edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        if (err != OK) {
1464edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            mConnectingDataSource.clear();
1465edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
1466edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            LOGI("mConnectingDataSource->connect() returned %d", err);
1467edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            return err;
1468edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        }
1469edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
14704d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber#if 0
14714d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        mCachedSource = new NuCachedSource2(
14724d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber                new ThrottledSource(
14734d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber                    mConnectingDataSource, 50 * 1024 /* bytes/sec */));
14744d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber#else
14754d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        mCachedSource = new NuCachedSource2(mConnectingDataSource);
14764d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber#endif
1477edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        mConnectingDataSource.clear();
14784d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
14794d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        dataSource = mCachedSource;
1480a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1481a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        // We're going to prefill the cache before trying to instantiate
1482a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        // the extractor below, as the latter is an operation that otherwise
1483a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        // could block on the datasource for a significant amount of time.
1484a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        // During that time we'd be unable to abort the preparation phase
1485a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        // without this prefill.
1486a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1487a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        mLock.unlock();
1488a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1489a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        for (;;) {
1490a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            bool eos;
1491a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            size_t cachedDataRemaining =
1492a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber                mCachedSource->approxDataRemaining(&eos);
1493a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1494a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            if (eos || cachedDataRemaining >= kHighWaterMarkBytes
1495a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber                    || (mFlags & PREPARE_CANCELLED)) {
1496a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber                break;
1497a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            }
1498a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1499a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            usleep(200000);
1500a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        }
1501a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1502a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        mLock.lock();
1503a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber
1504a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        if (mFlags & PREPARE_CANCELLED) {
1505a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            LOGI("Prepare cancelled while waiting for initial cache fill.");
1506a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber            return UNKNOWN_ERROR;
1507a2ab9aace3f7c2b283e6244a510a6378ce4650c3Andreas Huber        }
1508202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber    } else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
1509202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber        String8 uri("http://");
1510202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber        uri.append(mUri.string() + 11);
1511202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber
151254d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber        sp<LiveSource> liveSource = new LiveSource(uri.string());
1513202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber
151454d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber        mCachedSource = new NuCachedSource2(liveSource);
15154d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        dataSource = mCachedSource;
1516202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber
1517202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber        sp<MediaExtractor> extractor =
1518202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber            MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
15194d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber
152054d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber        static_cast<MPEG2TSExtractor *>(extractor.get())
152154d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber            ->setLiveSource(liveSource);
152254d09724e3ea2af4e08dff47d7ade92a95784127Andreas Huber
15234d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber        return setDataSource_l(extractor);
15248741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd    } else if (!strncmp("rtsp://gtalk/", mUri.string(), 13)) {
152557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        if (mLooper == NULL) {
152657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            mLooper = new ALooper;
1527c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber            mLooper->setName("gtalk rtp");
15283eaa3006a8230bd607375bedd79b2e328b0fc6b7Andreas Huber            mLooper->start(
15293eaa3006a8230bd607375bedd79b2e328b0fc6b7Andreas Huber                    false /* runOnCallingThread */,
15303eaa3006a8230bd607375bedd79b2e328b0fc6b7Andreas Huber                    false /* canCallJava */,
15313eaa3006a8230bd607375bedd79b2e328b0fc6b7Andreas Huber                    PRIORITY_HIGHEST);
153257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        }
153357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
15348741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        const char *startOfCodecString = &mUri.string()[13];
15358741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        const char *startOfSlash1 = strchr(startOfCodecString, '/');
15368741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        if (startOfSlash1 == NULL) {
15378741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            return BAD_VALUE;
15388741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        }
15398741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        const char *startOfWidthString = &startOfSlash1[1];
15408741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        const char *startOfSlash2 = strchr(startOfWidthString, '/');
15418741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        if (startOfSlash2 == NULL) {
15428741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            return BAD_VALUE;
15438741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        }
15448741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        const char *startOfHeightString = &startOfSlash2[1];
15458741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd
15468741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        String8 codecString(startOfCodecString, startOfSlash1 - startOfCodecString);
15478741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        String8 widthString(startOfWidthString, startOfSlash2 - startOfWidthString);
15488741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        String8 heightString(startOfHeightString);
15498741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd
155057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if 0
155157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mRTPPusher = new UDPPusher("/data/misc/rtpout.bin", 5434);
155257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mLooper->registerHandler(mRTPPusher);
155357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
155457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mRTCPPusher = new UDPPusher("/data/misc/rtcpout.bin", 5435);
155557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mLooper->registerHandler(mRTCPPusher);
155657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif
155757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
155857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mRTPSession = new ARTPSession;
155957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mLooper->registerHandler(mRTPSession);
156057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
156157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if 0
156257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        // My AMR SDP
156357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        static const char *raw =
156457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "v=0\r\n"
156557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
156657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "s=QuickTime\r\n"
156757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "t=0 0\r\n"
156857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "a=range:npt=0-315\r\n"
156957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "a=isma-compliance:2,2.0,2\r\n"
157057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "m=audio 5434 RTP/AVP 97\r\n"
157157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "c=IN IP4 127.0.0.1\r\n"
157257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "b=AS:30\r\n"
157357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "a=rtpmap:97 AMR/8000/1\r\n"
157457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "a=fmtp:97 octet-align\r\n";
157557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#elif 1
15768741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        String8 sdp;
15778741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        sdp.appendFormat(
157857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "v=0\r\n"
157957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
158057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "s=QuickTime\r\n"
158157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "t=0 0\r\n"
158257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "a=range:npt=0-315\r\n"
158357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "a=isma-compliance:2,2.0,2\r\n"
158457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "m=video 5434 RTP/AVP 97\r\n"
158557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "c=IN IP4 127.0.0.1\r\n"
158657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            "b=AS:30\r\n"
15878741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            "a=rtpmap:97 %s/90000\r\n"
15888741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            "a=cliprect:0,0,%s,%s\r\n"
15898741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            "a=framesize:97 %s-%s\r\n",
15908741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd
15918741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            codecString.string(),
15928741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            heightString.string(), widthString.string(),
15938741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            widthString.string(), heightString.string()
15948741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd            );
15958741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd        const char *raw = sdp.string();
15968741dfacf2ed0520e06b93af5109fa3b6042e4f6Mike Dodd
159757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif
159857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
159957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        sp<ASessionDescription> desc = new ASessionDescription;
160057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        CHECK(desc->setTo(raw, strlen(raw)));
160157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
160257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        CHECK_EQ(mRTPSession->setup(desc), (status_t)OK);
160357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
160457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        if (mRTPPusher != NULL) {
160557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            mRTPPusher->start();
160657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        }
160757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
160857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        if (mRTCPPusher != NULL) {
160957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            mRTCPPusher->start();
161057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        }
161157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
161257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        CHECK_EQ(mRTPSession->countTracks(), 1u);
161357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        sp<MediaSource> source = mRTPSession->trackAt(0);
161457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
161557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if 0
161657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        bool eos;
161757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        while (((APacketSource *)source.get())
161857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber                ->getQueuedDuration(&eos) < 5000000ll && !eos) {
161957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            usleep(100000ll);
162057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        }
162157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif
162257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
162357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        const char *mime;
162457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
162557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
162657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        if (!strncasecmp("video/", mime, 6)) {
162757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            setVideoSource(source);
162857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        } else {
162957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            CHECK(!strncasecmp("audio/", mime, 6));
163057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber            setAudioSource(source);
163157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        }
163257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
163357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        mExtractorFlags = MediaExtractor::CAN_PAUSE;
163457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber
163557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber        return OK;
16367a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber    } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
16377a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        if (mLooper == NULL) {
16387a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            mLooper = new ALooper;
1639c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber            mLooper->setName("rtsp");
16407a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            mLooper->start();
16417a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
16427a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        mRTSPController = new ARTSPController(mLooper);
16437a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        status_t err = mRTSPController->connect(mUri.string());
16447a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
16457a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        LOGI("ARTSPController::connect returned %d", err);
16467a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber
16477a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        if (err != OK) {
16487a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            mRTSPController.clear();
16497a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber            return err;
16507a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        }
1651202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber
16527a747b8e0dadf909ea4ac0b67fd88fc14b4eb3f8Andreas Huber        sp<MediaExtractor> extractor = mRTSPController.get();
1653202348e0d4aa07e81fc5b2fb2fd6340131d752ceAndreas Huber        return setDataSource_l(extractor);
1654edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    } else {
1655edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
1656edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    }
1657ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1658ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (dataSource == NULL) {
1659ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        return UNKNOWN_ERROR;
1660ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
1661ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1662ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
1663ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1664ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (extractor == NULL) {
1665ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        return UNKNOWN_ERROR;
1666ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
1667ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
1668ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    return setDataSource_l(extractor);
1669ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber}
1670ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
16713ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Hubervoid AwesomePlayer::abortPrepare(status_t err) {
16723ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    CHECK(err != OK);
16733ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber
16743ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    if (mIsAsyncPrepare) {
16753ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber        notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
16763ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    }
16773ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber
16783ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mPrepareResult = err;
1679edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    mFlags &= ~(PREPARING|PREPARE_CANCELLED);
16803ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mAsyncPrepareEvent = NULL;
16813ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber    mPreparedCondition.broadcast();
16823ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber}
16833ac94efc21c9dbcdf83ab2c630ab35dce229c9dcAndreas Huber
1684f71daba4cd68882442c043b636c754acf8fd942fAndreas Huber// static
1685f71daba4cd68882442c043b636c754acf8fd942fAndreas Huberbool AwesomePlayer::ContinuePreparation(void *cookie) {
1686f71daba4cd68882442c043b636c754acf8fd942fAndreas Huber    AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
1687f71daba4cd68882442c043b636c754acf8fd942fAndreas Huber
1688f71daba4cd68882442c043b636c754acf8fd942fAndreas Huber    return (me->mFlags & PREPARE_CANCELLED) == 0;
1689f71daba4cd68882442c043b636c754acf8fd942fAndreas Huber}
1690f71daba4cd68882442c043b636c754acf8fd942fAndreas Huber
16916be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Hubervoid AwesomePlayer::onPrepareAsyncEvent() {
169287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    Mutex::Autolock autoLock(mLock);
1693ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
169487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mFlags & PREPARE_CANCELLED) {
169587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        LOGI("prepare was cancelled before doing anything");
169687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        abortPrepare(UNKNOWN_ERROR);
169787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        return;
169887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    }
1699edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
170087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mUri.size() > 0) {
170187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        status_t err = finishSetDataSource_l();
1702ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
170387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        if (err != OK) {
170487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            abortPrepare(err);
170587ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            return;
1706ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        }
170787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    }
1708ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber
170987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mVideoTrack != NULL && mVideoSource == NULL) {
171087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        status_t err = initVideoDecoder();
171155864df7b64d14a79fe3a193f3bb0005f64b9452Andreas Huber
171287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        if (err != OK) {
171387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            abortPrepare(err);
171487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            return;
171555864df7b64d14a79fe3a193f3bb0005f64b9452Andreas Huber        }
171687ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    }
171755864df7b64d14a79fe3a193f3bb0005f64b9452Andreas Huber
171887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mAudioTrack != NULL && mAudioSource == NULL) {
171987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        status_t err = initAudioDecoder();
172055864df7b64d14a79fe3a193f3bb0005f64b9452Andreas Huber
172187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        if (err != OK) {
172287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            abortPrepare(err);
172387ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber            return;
172455864df7b64d14a79fe3a193f3bb0005f64b9452Andreas Huber        }
17256be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    }
17266be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
172787ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    if (mCachedSource != NULL || mRTSPController != NULL) {
172887ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        postBufferingEvent_l();
172987ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    } else {
173087ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber        finishAsyncPrepare_l();
173187ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber    }
173287ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Huber}
17336be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
173487ab9cdd0fde6bfb1205805c6a13423aafadeaaaAndreas Hubervoid AwesomePlayer::finishAsyncPrepare_l() {
1735ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    if (mIsAsyncPrepare) {
1736ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        if (mVideoWidth < 0 || mVideoHeight < 0) {
1737ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
1738ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        } else {
173931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            int32_t rotationDegrees;
174031dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            if (!mVideoTrack->getFormat()->findInt32(
174131dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                        kKeyRotation, &rotationDegrees)) {
174231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                rotationDegrees = 0;
174331dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            }
174431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber
174531dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber#if 1
174631dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            if (rotationDegrees == 90 || rotationDegrees == 270) {
174731dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                notifyListener_l(
174831dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                        MEDIA_SET_VIDEO_SIZE, mVideoHeight, mVideoWidth);
174931dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            } else
175031dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber#endif
175131dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            {
175231dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                notifyListener_l(
175331dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                        MEDIA_SET_VIDEO_SIZE, mVideoWidth, mVideoHeight);
175431dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber            }
1755ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        }
17566be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1757ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber        notifyListener_l(MEDIA_PREPARED);
1758ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    }
17596be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1760ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mPrepareResult = OK;
1761edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    mFlags &= ~(PREPARING|PREPARE_CANCELLED);
1762ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mFlags |= PREPARED;
17636be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber    mAsyncPrepareEvent = NULL;
1764ffdf4782d43df5fc59808de60c346f1edd695bd9Andreas Huber    mPreparedCondition.broadcast();
17656be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber}
17666be780ebd4d5733857e539b5dd30b532cd0fad80Andreas Huber
1767ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huberstatus_t AwesomePlayer::suspend() {
1768edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    LOGV("suspend");
1769ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex::Autolock autoLock(mLock);
1770ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1771ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    if (mSuspensionState != NULL) {
1772b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang        if (mLastVideoBuffer == NULL) {
1773b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            //go into here if video is suspended again
1774b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            //after resuming without being played between
1775b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            //them
1776b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            SuspensionState *state = mSuspensionState;
1777b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            mSuspensionState = NULL;
1778b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            reset_l();
1779b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            mSuspensionState = state;
1780b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang            return OK;
1781b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang        }
1782b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang
1783b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang        delete mSuspensionState;
1784b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang        mSuspensionState = NULL;
1785ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
1786ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1787edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    if (mFlags & PREPARING) {
1788edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        mFlags |= PREPARE_CANCELLED;
1789edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        if (mConnectingDataSource != NULL) {
1790edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            LOGI("interrupting the connection process");
1791edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber            mConnectingDataSource->disconnect();
1792edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber        }
1793edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    }
1794edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber
1795ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    while (mFlags & PREPARING) {
1796ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        mPreparedCondition.wait(mLock);
1797ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
1798ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1799ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    SuspensionState *state = new SuspensionState;
1800ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    state->mUri = mUri;
1801ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    state->mUriHeaders = mUriHeaders;
1802ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    state->mFileSource = mFileSource;
1803ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
18049fee0b2a02daa6fcf286ed930e45400dd3ba8dbaAndreas Huber    state->mFlags = mFlags & (PLAYING | AUTO_LOOPING | LOOPING | AT_EOS);
1805252573cb821259e883843630e6d69317cfb76850Andreas Huber    getPosition(&state->mPositionUs);
1806ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
18077b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    if (mLastVideoBuffer) {
18087b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        size_t size = mLastVideoBuffer->range_length();
18091e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
18107b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        if (size) {
18111e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber            int32_t unreadable;
18121e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber            if (!mLastVideoBuffer->meta_data()->findInt32(
18131e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                        kKeyIsUnreadable, &unreadable)
18141e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                    || unreadable == 0) {
18151e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                state->mLastVideoFrameSize = size;
18161e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                state->mLastVideoFrame = malloc(size);
18171e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                memcpy(state->mLastVideoFrame,
18181e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                       (const uint8_t *)mLastVideoBuffer->data()
18191e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                            + mLastVideoBuffer->range_offset(),
18201e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                       size);
18211e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
18221e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                state->mVideoWidth = mVideoWidth;
18231e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                state->mVideoHeight = mVideoHeight;
18241e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber
18251e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                sp<MetaData> meta = mVideoSource->getFormat();
18261e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat));
18271e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth));
18281e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight));
18291e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber            } else {
18301e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                LOGV("Unable to save last video frame, we have no access to "
18311e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber                     "the decoded video data.");
18321e1941638398e5e3e1d7b9ad88e66f574576bcfaAndreas Huber            }
18337b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        }
18347b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    }
18357b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
1836ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    reset_l();
1837ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1838ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mSuspensionState = state;
1839ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1840ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    return OK;
1841ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber}
1842ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1843ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huberstatus_t AwesomePlayer::resume() {
1844edbb4d8f398dfbce7b766d4bd207685dab582847Andreas Huber    LOGV("resume");
1845ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex::Autolock autoLock(mLock);
1846ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1847ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    if (mSuspensionState == NULL) {
1848ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        return INVALID_OPERATION;
1849ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
1850ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1851ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    SuspensionState *state = mSuspensionState;
1852ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    mSuspensionState = NULL;
1853ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1854ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    status_t err;
1855ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    if (state->mFileSource != NULL) {
1856ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        err = setDataSource_l(state->mFileSource);
1857ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1858ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        if (err == OK) {
1859ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber            mFileSource = state->mFileSource;
1860ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        }
1861ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    } else {
1862ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        err = setDataSource_l(state->mUri, &state->mUriHeaders);
1863ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
1864ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1865ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    if (err != OK) {
1866ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        delete state;
1867ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        state = NULL;
1868ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1869ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        return err;
1870ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
1871ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1872ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    seekTo_l(state->mPositionUs);
1873ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
18749fee0b2a02daa6fcf286ed930e45400dd3ba8dbaAndreas Huber    mFlags = state->mFlags & (AUTO_LOOPING | LOOPING | AT_EOS);
1875ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
18767b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    if (state->mLastVideoFrame && mISurface != NULL) {
18777b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        mVideoRenderer =
18787b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber            new AwesomeLocalRenderer(
18797b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    true,  // previewOnly
18807b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    "",
18817b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    (OMX_COLOR_FORMATTYPE)state->mColorFormat,
18827b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    mISurface,
18837b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    state->mVideoWidth,
18847b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    state->mVideoHeight,
18857b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                    state->mDecodedWidth,
188631dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    state->mDecodedHeight,
188731dc911aee2b50752c0eb7785176075cdaed139cAndreas Huber                    0);
18887b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
18897b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        mVideoRendererIsPreview = true;
18907b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
18917b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber        ((AwesomeLocalRenderer *)mVideoRenderer.get())->render(
18927b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber                state->mLastVideoFrame, state->mLastVideoFrameSize);
18937b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber    }
18947b73cfcc7530114ac81556bb9c58aff4181da92dAndreas Huber
1895ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    if (state->mFlags & PLAYING) {
1896ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        play_l();
1897ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    }
1898ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1899b19da8e187db1cf223463809148b7cb2d9e9751aGloria Wang    mSuspensionState = state;
1900ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    state = NULL;
1901ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1902ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    return OK;
1903ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber}
1904ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
190562f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huberuint32_t AwesomePlayer::flags() const {
190662f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber    return mExtractorFlags;
190762f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber}
190862f7ffe106a7126ef31b199552c5cfc6599bc3d1Andreas Huber
19092b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Hubervoid AwesomePlayer::postAudioEOS() {
19102b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber    postCheckAudioStatusEvent_l();
19112b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber}
19122b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber
19132b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Hubervoid AwesomePlayer::postAudioSeekComplete() {
19142b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber    postCheckAudioStatusEvent_l();
19152b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber}
19162b359ed5b5ba4775609c13408b2cf1336c2cc45bAndreas Huber
191727366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber}  // namespace android
191827366fc9540cb642ee4856957dabffe7ddf1f901Andreas Huber
1919