AwesomePlayer.cpp revision 0a5baa9b411fe086013d2a5e9126ed63fbad046c
1986b8f798272d3ae2898617c8fb089156a5941c0Ian Romanick/*
2a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Copyright (C) 2009 The Android Open Source Project
3a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *
4a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Licensed under the Apache License, Version 2.0 (the "License");
5a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * you may not use this file except in compliance with the License.
6a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * You may obtain a copy of the License at
7a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *
8a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *      http://www.apache.org/licenses/LICENSE-2.0
9a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick *
10a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * Unless required by applicable law or agreed to in writing, software
11a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * distributed under the License is distributed on an "AS IS" BASIS,
12a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * See the License for the specific language governing permissions and
14a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick * limitations under the License.
15a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick */
16a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
17a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick//#define LOG_NDEBUG 0
18a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#define LOG_TAG "AwesomePlayer"
19a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include <utils/Log.h>
20a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
21a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include <dlfcn.h>
22a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
23a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include "include/ARTSPController.h"
24a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#include "include/AwesomePlayer.h"
25e309a6051d1a04ee581f0a47c6c585918fba1096Ian Romanick#include "include/LiveSource.h"
26e309a6051d1a04ee581f0a47c6c585918fba1096Ian Romanick#include "include/SoftwareRenderer.h"
27e309a6051d1a04ee581f0a47c6c585918fba1096Ian Romanick#include "include/NuCachedSource2.h"
28e309a6051d1a04ee581f0a47c6c585918fba1096Ian Romanick#include "include/ThrottledSource.h"
29ac95f2f8c88d39aaa878f61172d9748af13e2c80Eric Anholt
30ac95f2f8c88d39aaa878f61172d9748af13e2c80Eric Anholt#include <binder/IPCThreadState.h>
31ac95f2f8c88d39aaa878f61172d9748af13e2c80Eric Anholt#include <media/stagefright/AudioPlayer.h>
32f961e4458f1e894ca782c1627b69cdee993a16f8Carl Worth#include <media/stagefright/DataSource.h>
33f961e4458f1e894ca782c1627b69cdee993a16f8Carl Worth#include <media/stagefright/FileSource.h>
34f961e4458f1e894ca782c1627b69cdee993a16f8Carl Worth#include <media/stagefright/MediaBuffer.h>
35f961e4458f1e894ca782c1627b69cdee993a16f8Carl Worth#include <media/stagefright/MediaDefs.h>
3611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick#include <media/stagefright/MediaExtractor.h>
370044e7edcea22d2456c051a1c4b744a26960ad27Ian Romanick#include <media/stagefright/MediaDebug.h>
3878b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick#include <media/stagefright/MediaSource.h>
398895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick#include <media/stagefright/MetaData.h>
400044e7edcea22d2456c051a1c4b744a26960ad27Ian Romanick#include <media/stagefright/OMXCodec.h>
41e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
42e053d62aa573651abdd78666d299272c8219a3aaIan Romanick#include <surfaceflinger/ISurface.h>
43e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
44e053d62aa573651abdd78666d299272c8219a3aaIan Romanick#include <media/stagefright/foundation/ALooper.h>
45e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
46e053d62aa573651abdd78666d299272c8219a3aaIan Romanicknamespace android {
47e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
48e053d62aa573651abdd78666d299272c8219a3aaIan Romanickstruct AwesomeEvent : public TimedEventQueue::Event {
49e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    AwesomeEvent(
50e053d62aa573651abdd78666d299272c8219a3aaIan Romanick            AwesomePlayer *player,
51e053d62aa573651abdd78666d299272c8219a3aaIan Romanick            void (AwesomePlayer::*method)())
52e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        : mPlayer(player),
53e053d62aa573651abdd78666d299272c8219a3aaIan Romanick          mMethod(method) {
54e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    }
55e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
56e053d62aa573651abdd78666d299272c8219a3aaIan Romanickprotected:
57e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    virtual ~AwesomeEvent() {}
58e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
59e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
60e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        (mPlayer->*mMethod)();
61d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    }
62e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
63e053d62aa573651abdd78666d299272c8219a3aaIan Romanickprivate:
64e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    AwesomePlayer *mPlayer;
65e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    void (AwesomePlayer::*mMethod)();
66d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
67d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    AwesomeEvent(const AwesomeEvent &);
68d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    AwesomeEvent &operator=(const AwesomeEvent &);
69d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt};
70d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
71d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholtstruct AwesomeRemoteRenderer : public AwesomeRenderer {
72d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    AwesomeRemoteRenderer(const sp<IOMXRenderer> &target)
73d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        : mTarget(target) {
74d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    }
75d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
76d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    virtual void render(MediaBuffer *buffer) {
77d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        void *id;
78d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) {
79d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt            mTarget->render((IOMX::buffer_id)id);
80d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        }
81d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    }
82d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
83d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholtprivate:
846dc89d221d43fad5f3edbb903997160af071bec0Brian Paul    sp<IOMXRenderer> mTarget;
85d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
86d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    AwesomeRemoteRenderer(const AwesomeRemoteRenderer &);
87a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    AwesomeRemoteRenderer &operator=(const AwesomeRemoteRenderer &);
88a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick};
89a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
900044e7edcea22d2456c051a1c4b744a26960ad27Ian Romanickstruct AwesomeLocalRenderer : public AwesomeRenderer {
91a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    AwesomeLocalRenderer(
92d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt            bool previewOnly,
93a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            const char *componentName,
94a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            OMX_COLOR_FORMATTYPE colorFormat,
95e46a454305af64710ce8deadafc718f75363ac7eEric Anholt            const sp<ISurface> &surface,
964b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt            size_t displayWidth, size_t displayHeight,
97e46a454305af64710ce8deadafc718f75363ac7eEric Anholt            size_t decodedWidth, size_t decodedHeight)
9878b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick        : mTarget(NULL),
998895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick          mLibHandle(NULL) {
1008273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt            init(previewOnly, componentName,
1018273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt                 colorFormat, surface, displayWidth,
10278b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick                 displayHeight, decodedWidth, decodedHeight);
10344e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke    }
10444e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke
10544e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke    virtual void render(MediaBuffer *buffer) {
10644e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke        render((const uint8_t *)buffer->data() + buffer->range_offset(),
10744e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke               buffer->range_length());
10844e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke    }
10944e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke
11044e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke    void render(const void *data, size_t size) {
11144e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke        mTarget->render(data, size, NULL);
1126202cbfe3614141e330501959a7322522b35f4e4Kenneth Graunke    }
11344e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke
114b145e903694fa932ab1e0d955e889555193ab604Eric Anholtprotected:
115d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    virtual ~AwesomeLocalRenderer() {
1166d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt        delete mTarget;
117fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        mTarget = NULL;
11801f8de4a87157b01e8b9fe31c6766a15bbfb2788Ian Romanick
119cad9766118d269725ef33b4e9588d674d5225010Eric Anholt        if (mLibHandle) {
120cad9766118d269725ef33b4e9588d674d5225010Eric Anholt            dlclose(mLibHandle);
121cad9766118d269725ef33b4e9588d674d5225010Eric Anholt            mLibHandle = NULL;
1225ba94206083fcd678febd6cac0231f35c0f1b77aEric Anholt        }
1237d21104a8b92c139051e9a224c5d863802a8ade6Eric Anholt    }
1245c89f0ecb9581cbe83442ab3f41f2f3701fffab0Eric Anholt
12544e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunkeprivate:
12644e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke    VideoRenderer *mTarget;
127a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    void *mLibHandle;
12844e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke
129d27ec2461bca2625d09a3592ec8cc4137d4347f3Ian Romanick    void init(
130d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt            bool previewOnly,
1310a89175a35ba3ac2a94d0ba9bcc9926edc8927e3Kenneth Graunke            const char *componentName,
132d27ec2461bca2625d09a3592ec8cc4137d4347f3Ian Romanick            OMX_COLOR_FORMATTYPE colorFormat,
133a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            const sp<ISurface> &surface,
134a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            size_t displayWidth, size_t displayHeight,
135a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            size_t decodedWidth, size_t decodedHeight);
136fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke
137fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    AwesomeLocalRenderer(const AwesomeLocalRenderer &);
1388273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt    AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
139ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanick};
140fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke
141fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunkevoid AwesomeLocalRenderer::init(
142fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        bool previewOnly,
143fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        const char *componentName,
144fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        OMX_COLOR_FORMATTYPE colorFormat,
145fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        const sp<ISurface> &surface,
146fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        size_t displayWidth, size_t displayHeight,
147fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        size_t decodedWidth, size_t decodedHeight) {
148fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    if (!previewOnly) {
149fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        // We will stick to the vanilla software-color-converting renderer
150fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        // for "previewOnly" mode, to avoid unneccessarily switching overlays
151fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        // more often than necessary.
1522b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick
1532b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick        mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
1542b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick
1552b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick        if (mLibHandle) {
1562b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick            typedef VideoRenderer *(*CreateRendererFunc)(
1572b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick                    const sp<ISurface> &surface,
1582b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick                    const char *componentName,
1592b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick                    OMX_COLOR_FORMATTYPE colorFormat,
160b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                    size_t displayWidth, size_t displayHeight,
161b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                    size_t decodedWidth, size_t decodedHeight);
162b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick
163b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            CreateRendererFunc func =
164b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                (CreateRendererFunc)dlsym(
165b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                        mLibHandle,
166b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                        "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
167b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                        "OMX_COLOR_FORMATTYPEjjjj");
168b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick
169b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            if (func) {
170b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                mTarget =
171b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                    (*func)(surface, componentName, colorFormat,
172b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                        displayWidth, displayHeight,
173b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                        decodedWidth, decodedHeight);
174b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            }
175ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick        }
176ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick    }
177ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick
178ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick    if (mTarget == NULL) {
179ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick        mTarget = new SoftwareRenderer(
180ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick                colorFormat, surface, displayWidth, displayHeight,
181ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick                decodedWidth, decodedHeight);
182ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick    }
1838e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick}
184ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick
185ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan RomanickAwesomePlayer::AwesomePlayer()
186ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick    : mQueueStarted(false),
187ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mTimeSource(NULL),
188ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mVideoRendererIsPreview(false),
189ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mAudioPlayer(NULL),
190ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mFlags(0),
191ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mExtractorFlags(0),
192ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mLastVideoBuffer(NULL),
193ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mVideoBuffer(NULL),
194ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick      mSuspensionState(NULL) {
1958e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    CHECK_EQ(mClient.connect(), OK);
196ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick
197ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick    DataSource::RegisterDefaultSniffers();
198ad87f2ddc7e6b95e3dd5bbe4d2b19703d305c74eIan Romanick
1998e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
2008e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mVideoEventPending = false;
2018e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
2028e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mStreamDoneEventPending = false;
2038e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
2048e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mBufferingEventPending = false;
2058e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick
2068e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mCheckAudioStatusEvent = new AwesomeEvent(
2078e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick            this, &AwesomePlayer::onCheckAudioStatus);
2088e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick
2098e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick    mAudioStatusEventPending = false;
2108e498050dc1a1285c2218fdf4ea506c1cdcd9dd8Ian Romanick
211fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    reset();
2120a89175a35ba3ac2a94d0ba9bcc9926edc8927e3Kenneth Graunke}
213fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke
214fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth GraunkeAwesomePlayer::~AwesomePlayer() {
215fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    if (mQueueStarted) {
216e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        mQueue.stop();
217e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    }
218e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
219a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    reset();
220e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
221e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    mClient.disconnect();
222a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
223a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
2247e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanickvoid AwesomePlayer::cancelPlayerEvents(bool keepBufferingGoing) {
2257e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick    mQueue.cancelEvent(mVideoEvent->eventID());
226a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mVideoEventPending = false;
227a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mQueue.cancelEvent(mStreamDoneEvent->eventID());
228a22426dc4c934673e8f0af5c70a67505a4de7aadCarl Worth    mStreamDoneEventPending = false;
229a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
230a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mAudioStatusEventPending = false;
231a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
232a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    if (!keepBufferingGoing) {
233a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        mQueue.cancelEvent(mBufferingEvent->eventID());
234fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        mBufferingEventPending = false;
235a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    }
236a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
2377e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick
238a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickvoid AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
2398273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt    Mutex::Autolock autoLock(mLock);
2404b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt    mListener = listener;
24144e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke}
24244e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke
24344e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunkestatus_t AwesomePlayer::setDataSource(
24444e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke        const char *uri, const KeyedVector<String8, String8> *headers) {
24544e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke    Mutex::Autolock autoLock(mLock);
24678b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    return setDataSource_l(uri, headers);
24778b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick}
24878b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick
24978b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanickstatus_t AwesomePlayer::setDataSource_l(
25078b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick        const char *uri, const KeyedVector<String8, String8> *headers) {
2518895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick    reset_l();
2528895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick
2532d394d4877794d19756c3760d711524dca89f772Ian Romanick    mUri = uri;
254950ceb2bd60c25e7fecdff0fbcbf6e69015588f3Ian Romanick
255950ceb2bd60c25e7fecdff0fbcbf6e69015588f3Ian Romanick    if (headers) {
256950ceb2bd60c25e7fecdff0fbcbf6e69015588f3Ian Romanick        mUriHeaders = *headers;
257046bef235744e891e4a48076e1a3ff9a61a63092Eric Anholt    }
258046bef235744e891e4a48076e1a3ff9a61a63092Eric Anholt
259046bef235744e891e4a48076e1a3ff9a61a63092Eric Anholt    // The actual work will be done during preparation in the call to
260046bef235744e891e4a48076e1a3ff9a61a63092Eric Anholt    // ::finishSetDataSource_l to avoid blocking the calling thread in
261950ceb2bd60c25e7fecdff0fbcbf6e69015588f3Ian Romanick    // setDataSource for any significant time.
262950ceb2bd60c25e7fecdff0fbcbf6e69015588f3Ian Romanick
263950ceb2bd60c25e7fecdff0fbcbf6e69015588f3Ian Romanick    return OK;
2648b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick}
2658b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick
2668b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanickstatus_t AwesomePlayer::setDataSource(
2678b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick        int fd, int64_t offset, int64_t length) {
2688b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick#if 0
2698b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick    // return setDataSource("httplive://iphoned5.akamai.com.edgesuite.net/mhbarron/nasatv/nasatv_96.m3u8");
2708b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick    // return setDataSource("httplive://iphoned5.akamai.com.edgesuite.net/mhbarron/nasatv/nasatv_1500.m3u8");
2718b80e9f9e3bc9ca41c95125826139471f73602c4Ian Romanick    return setDataSource("httplive://iphone.video.hsn.com/iPhone_high.m3u8");
272e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    // return setDataSource("httplive://iphoned5.akamai.com.edgesuite.net/mhbarron/iphonewebcast/webcast090209_all/webcast090209_all.m3u8");
273e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    // return setDataSource("httplive://qthttp.akamai.com.edgesuite.net/iphone_demo/Video_Content/usat/tt_062209_iphone/hi/prog_index.m3u8");
274e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    // return setDataSource("httplive://qthttp.akamai.com.edgesuite.net/iphone_demo/Video_Content/usat/tt_googmaps/hi/prog_index.m3u8");
275a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    // return setDataSource("httplive://qthttp.akamai.com.edgesuite.net/iphone_demo/Video_Content/mtv/ni_spo_25a_rt74137_clip_syn/hi/prog_index.m3u8");
276a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick#endif
277b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick
278b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick    Mutex::Autolock autoLock(mLock);
279b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick
280b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick    reset_l();
281b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick
282b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick    sp<DataSource> dataSource = new FileSource(fd, offset, length);
283b8a21cc6df7e9da15a24ed3dbf60cd4aeb8effaaIan Romanick
284e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    status_t err = dataSource->initCheck();
285e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
286e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    if (err != OK) {
287e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        return err;
288e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    }
289e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
290a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mFileSource = dataSource;
291a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
292a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    return setDataSource_l(dataSource);
293a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
294e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
295e053d62aa573651abdd78666d299272c8219a3aaIan Romanickstatus_t AwesomePlayer::setDataSource_l(
296e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        const sp<DataSource> &dataSource) {
297e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
298e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
299a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    if (extractor == NULL) {
300e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        return UNKNOWN_ERROR;
301e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    }
302e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
303e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    return setDataSource_l(extractor);
304e053d62aa573651abdd78666d299272c8219a3aaIan Romanick}
305e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
306a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatus_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
3079d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick    bool haveAudio = false;
3089d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick    bool haveVideo = false;
3099d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick    for (size_t i = 0; i < extractor->countTracks(); ++i) {
3109d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick        sp<MetaData> meta = extractor->getTrackMetaData(i);
3119d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick
3129d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick        const char *mime;
3139d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick        CHECK(meta->findCString(kKeyMIMEType, &mime));
3149d975377ca6dae7805804c0fbe625bb7c5f9e095Ian Romanick
315326c676236e6a3c90db63e4d0c893aa4f9c21876Eric Anholt        if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
316e053d62aa573651abdd78666d299272c8219a3aaIan Romanick            setVideoSource(extractor->getTrack(i));
317e053d62aa573651abdd78666d299272c8219a3aaIan Romanick            haveVideo = true;
318e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
319e053d62aa573651abdd78666d299272c8219a3aaIan Romanick            setAudioSource(extractor->getTrack(i));
3204a962170d7cf4243d6ae156fca20a6167388925dEric Anholt            haveAudio = true;
3214a962170d7cf4243d6ae156fca20a6167388925dEric Anholt        }
322e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
3234a962170d7cf4243d6ae156fca20a6167388925dEric Anholt        if (haveAudio && haveVideo) {
324326c676236e6a3c90db63e4d0c893aa4f9c21876Eric Anholt            break;
325eee68d3631813580a14fa51fda6f0c959279256cIan Romanick        }
326eee68d3631813580a14fa51fda6f0c959279256cIan Romanick    }
327eee68d3631813580a14fa51fda6f0c959279256cIan Romanick
328eee68d3631813580a14fa51fda6f0c959279256cIan Romanick    if (!haveAudio && !haveVideo) {
329eee68d3631813580a14fa51fda6f0c959279256cIan Romanick        return UNKNOWN_ERROR;
330eee68d3631813580a14fa51fda6f0c959279256cIan Romanick    }
331eee68d3631813580a14fa51fda6f0c959279256cIan Romanick
332eee68d3631813580a14fa51fda6f0c959279256cIan Romanick    mExtractorFlags = extractor->flags();
333eee68d3631813580a14fa51fda6f0c959279256cIan Romanick
33469a079aee8f79104501faeb2a5092b643f956d33Ian Romanick    return OK;
33569a079aee8f79104501faeb2a5092b643f956d33Ian Romanick}
33669a079aee8f79104501faeb2a5092b643f956d33Ian Romanick
33769a079aee8f79104501faeb2a5092b643f956d33Ian Romanickvoid AwesomePlayer::reset() {
33869a079aee8f79104501faeb2a5092b643f956d33Ian Romanick    Mutex::Autolock autoLock(mLock);
33969a079aee8f79104501faeb2a5092b643f956d33Ian Romanick    reset_l();
34069a079aee8f79104501faeb2a5092b643f956d33Ian Romanick}
34169a079aee8f79104501faeb2a5092b643f956d33Ian Romanick
34269a079aee8f79104501faeb2a5092b643f956d33Ian Romanickvoid AwesomePlayer::reset_l() {
34369a079aee8f79104501faeb2a5092b643f956d33Ian Romanick    if (mFlags & PREPARING) {
34469a079aee8f79104501faeb2a5092b643f956d33Ian Romanick        mFlags |= PREPARE_CANCELLED;
34569a079aee8f79104501faeb2a5092b643f956d33Ian Romanick        if (mConnectingDataSource != NULL) {
34669a079aee8f79104501faeb2a5092b643f956d33Ian Romanick            LOGI("interrupting the connection process");
34769a079aee8f79104501faeb2a5092b643f956d33Ian Romanick            mConnectingDataSource->disconnect();
34869a079aee8f79104501faeb2a5092b643f956d33Ian Romanick        }
34969a079aee8f79104501faeb2a5092b643f956d33Ian Romanick    }
35069a079aee8f79104501faeb2a5092b643f956d33Ian Romanick
351c178c74c27ab292651dcf7da02a7d035366cae04Ian Romanick    while (mFlags & PREPARING) {
352c178c74c27ab292651dcf7da02a7d035366cae04Ian Romanick        mPreparedCondition.wait(mLock);
353c178c74c27ab292651dcf7da02a7d035366cae04Ian Romanick    }
354c178c74c27ab292651dcf7da02a7d035366cae04Ian Romanick
355c178c74c27ab292651dcf7da02a7d035366cae04Ian Romanick    cancelPlayerEvents();
356326c676236e6a3c90db63e4d0c893aa4f9c21876Eric Anholt
357326c676236e6a3c90db63e4d0c893aa4f9c21876Eric Anholt    mCachedSource.clear();
358326c676236e6a3c90db63e4d0c893aa4f9c21876Eric Anholt    mAudioTrack.clear();
359a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mVideoTrack.clear();
360a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
361a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    // Shutdown audio first, so that the respone to the reset request
362a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    // appears to happen instantaneously as far as the user is concerned
3639fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke    // If we did this later, audio would continue playing while we
3649fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke    // shutdown the video-related resources and the player appear to
3659fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke    // not be as responsive to a reset request.
3669fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke    if (mAudioPlayer == NULL && mAudioSource != NULL) {
367a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        // If we had an audio player, it would have effectively
368894ea972a4defdaafeaa3a248c113b06c7ae0c7eEric Anholt        // taken possession of the audio source and stopped it when
369894ea972a4defdaafeaa3a248c113b06c7ae0c7eEric Anholt        // _it_ is stopped. Otherwise this is still our responsibility.
370894ea972a4defdaafeaa3a248c113b06c7ae0c7eEric Anholt        mAudioSource->stop();
371a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    }
372e39cc69fa3cb830b803fe0c4f6c30915aa886b5bIan Romanick    mAudioSource.clear();
373a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
3748273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt    if (mTimeSource != mAudioPlayer) {
3758273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt        delete mTimeSource;
3764b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt    }
37778b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    mTimeSource = NULL;
37878b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick
37978b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    delete mAudioPlayer;
38078b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    mAudioPlayer = NULL;
38178b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick
3828895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick    mVideoRenderer.clear();
3838895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick
384a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    if (mLastVideoBuffer) {
3850f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick        mLastVideoBuffer->release();
3860f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick        mLastVideoBuffer = NULL;
3870f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick    }
3880f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick
3890f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick    if (mVideoBuffer) {
390df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        mVideoBuffer->release();
391df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        mVideoBuffer = NULL;
392df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick    }
393df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick
394df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick    mRTSPController.clear();
395df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick
396df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick    if (mVideoSource != NULL) {
397df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        mVideoSource->stop();
398df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick
399df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        // The following hack is necessary to ensure that the OMX
400df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        // component is completely released by the time we may try
401df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        // to instantiate it again.
402df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        wp<MediaSource> tmp = mVideoSource;
403df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        mVideoSource.clear();
404df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        while (tmp.promote() != NULL) {
405df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick            usleep(1000);
406df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick        }
407abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke        IPCThreadState::self()->flushCommands();
408abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke    }
409abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke
410abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke    mDurationUs = -1;
411abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke    mFlags = 0;
412abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke    mExtractorFlags = 0;
413abd40b15210c17b2a3ba8fcffc868fda203efa01Kenneth Graunke    mVideoWidth = mVideoHeight = -1;
414bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke    mTimeSourceDeltaUs = 0;
415bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke    mVideoTimeUs = 0;
416bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke
417bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke    mSeeking = false;
418bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke    mSeekNotificationSent = false;
419bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke    mSeekTimeUs = 0;
420bff6013d469b3d4e54cdc5731801c56994a523ecKenneth Graunke
421a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mUri.setTo("");
422a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mUriHeaders.clear();
423a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
424a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mFileSource.clear();
425a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
426a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    delete mSuspensionState;
427a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mSuspensionState = NULL;
428f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt}
429f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt
430f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholtvoid AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
431f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt    if (mListener != NULL) {
432a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        sp<MediaPlayerBase> listener = mListener.promote();
4330044e7edcea22d2456c051a1c4b744a26960ad27Ian Romanick
434a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        if (listener != NULL) {
4359fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke            listener->sendEvent(msg, ext1, ext2);
4369fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke        }
4376a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick    }
438f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunke}
439f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunke
440f412fac5b46eb274cbed8e62234d5dbfd859f1feKenneth Graunkevoid AwesomePlayer::onBufferingUpdate() {
441894ea972a4defdaafeaa3a248c113b06c7ae0c7eEric Anholt    Mutex::Autolock autoLock(mLock);
442894ea972a4defdaafeaa3a248c113b06c7ae0c7eEric Anholt    if (!mBufferingEventPending) {
443894ea972a4defdaafeaa3a248c113b06c7ae0c7eEric Anholt        return;
4446a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick    }
4456a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick    mBufferingEventPending = false;
446df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick
4476a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick    if (mCachedSource == NULL) {
4486a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick        return;
449a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    }
450a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
451a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    size_t lowWatermark = 400000;
452a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    size_t highWatermark = 1000000;
4539fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke
4549fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke    off_t size;
4559fa99f3b6c84fe927ba97e6584cd919f097a6c9aKenneth Graunke    if (mDurationUs >= 0 && mCachedSource->getSize(&size) == OK) {
456a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        int64_t bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
457a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
458a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        size_t cachedSize = mCachedSource->cachedSize();
459882dad75408fc4071a9dd700309f9e54f6ad2650Ian Romanick        int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
460a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
4618273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt        double percentage = (double)cachedDurationUs / mDurationUs;
4624b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt
4636202cbfe3614141e330501959a7322522b35f4e4Kenneth Graunke        notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage * 100.0);
4646202cbfe3614141e330501959a7322522b35f4e4Kenneth Graunke
4656202cbfe3614141e330501959a7322522b35f4e4Kenneth Graunke        lowWatermark = 2 * bitrate / 8;  // 2 secs
4666202cbfe3614141e330501959a7322522b35f4e4Kenneth Graunke        highWatermark = 10 * bitrate / 8;  // 10 secs
4676202cbfe3614141e330501959a7322522b35f4e4Kenneth Graunke    }
46878b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick
46978b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    bool eos;
47078b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&eos);
47178b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick
47278b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    if ((mFlags & PLAYING) && !eos && (cachedDataRemaining < lowWatermark)) {
4738895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick        LOGI("cache is running low (< %d) , pausing.", lowWatermark);
4748895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick        mFlags |= CACHE_UNDERRUN;
4756a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick        pause_l();
4766a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
477df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick    } else if ((mFlags & CACHE_UNDERRUN)
478df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick            && (eos || cachedDataRemaining > highWatermark)) {
4796a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick        LOGI("cache has filled up (> %d), resuming.", highWatermark);
4806a15d5b514b703ff8dd024f96ffbcb68484a954eIan Romanick        mFlags &= ~CACHE_UNDERRUN;
481a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        play_l();
48295cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
48395cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick    }
48495cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick
48595cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick    postBufferingEvent_l();
48695cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick}
48795cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick
48895cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanickvoid AwesomePlayer::onStreamDone() {
48995cd6cc195f4652378d7ecf614c6e1c568311a04Ian Romanick    // Posted whenever any stream finishes playing.
4900d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke
4910d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke    Mutex::Autolock autoLock(mLock);
492471471f83471481db0445e73f8c89e6a9149838eIan Romanick    if (!mStreamDoneEventPending) {
493b95897b89d36a25c237a021c299a4eb295856476Ian Romanick        return;
494471471f83471481db0445e73f8c89e6a9149838eIan Romanick    }
495471471f83471481db0445e73f8c89e6a9149838eIan Romanick    mStreamDoneEventPending = false;
4960d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke
4970d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke    if (mStreamDoneStatus == ERROR_END_OF_STREAM && (mFlags & LOOPING)) {
4980d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke        seekTo_l(0);
499b95897b89d36a25c237a021c299a4eb295856476Ian Romanick
5000d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke        if (mVideoSource != NULL) {
5010d605cb97c9cd2f9a170e3aa15bdf4021a75fc14Kenneth Graunke            postVideoEvent_l();
502a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        }
503a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    } else {
504a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        if (mStreamDoneStatus == ERROR_END_OF_STREAM) {
505a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            LOGV("MEDIA_PLAYBACK_COMPLETE");
50681f03393982c29f8f4165b5629c8e8fb708b97a3Kenneth Graunke            notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
50781f03393982c29f8f4165b5629c8e8fb708b97a3Kenneth Graunke        } else {
508b6f15869b324ae64a00d0fe46fa3c8c62c1edb6cKenneth Graunke            LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
509471471f83471481db0445e73f8c89e6a9149838eIan Romanick
510f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt            notifyListener_l(
511471471f83471481db0445e73f8c89e6a9149838eIan Romanick                    MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
5120044e7edcea22d2456c051a1c4b744a26960ad27Ian Romanick        }
513a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
5140f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick        pause_l();
5150f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick
5160f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick        mFlags |= AT_EOS;
517df05ad4e1aa5512ce1dfd2e6661641e012c8b279Ian Romanick    }
5180f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick}
519a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
520a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatus_t AwesomePlayer::play() {
521a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    Mutex::Autolock autoLock(mLock);
5223c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5233c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    mFlags &= ~CACHE_UNDERRUN;
5243c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5253c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    return play_l();
5263c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick}
5273c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5283c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanickstatus_t AwesomePlayer::play_l() {
5293c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    if (mFlags & PLAYING) {
530d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        return OK;
5313c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    }
5323c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5338273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt    if (!(mFlags & PREPARED)) {
5344b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt        status_t err = prepare_l();
5355ba94206083fcd678febd6cac0231f35c0f1b77aEric Anholt
5365ba94206083fcd678febd6cac0231f35c0f1b77aEric Anholt        if (err != OK) {
5375ba94206083fcd678febd6cac0231f35c0f1b77aEric Anholt            return err;
5385ba94206083fcd678febd6cac0231f35c0f1b77aEric Anholt        }
5395ba94206083fcd678febd6cac0231f35c0f1b77aEric Anholt    }
5403c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5413c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    mFlags |= PLAYING;
5423c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    mFlags |= FIRST_FRAME;
5433c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5443c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick    bool deferredAudioSeek = false;
5458895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick
5468895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick    if (mAudioSource != NULL) {
5473c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick        if (mAudioPlayer == NULL) {
548f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt            if (mAudioSink != NULL) {
5493c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick                mAudioPlayer = new AudioPlayer(mAudioSink);
550f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt                mAudioPlayer->setSource(mAudioSource);
5513c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick
5523c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick                // We've already started the MediaSource in order to enable
5533c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick                // the prefetcher to read its data.
5543c6fea3048a0d9add2fec621d30c32f3519d8868Ian Romanick                status_t err = mAudioPlayer->start(
555fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                        true /* sourceAlreadyStarted */);
556fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
557fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                if (err != OK) {
558fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                    delete mAudioPlayer;
559fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                    mAudioPlayer = NULL;
5603b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick
561fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                    mFlags &= ~(PLAYING | FIRST_FRAME);
5628273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
5634b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt                    return err;
564fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                }
565fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
566fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                delete mTimeSource;
567fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick                mTimeSource = mAudioPlayer;
568fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
5698895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick                deferredAudioSeek = true;
5708895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick
57101f8de4a87157b01e8b9fe31c6766a15bbfb2788Ian Romanick                mWatchForAudioSeekComplete = false;
57201f8de4a87157b01e8b9fe31c6766a15bbfb2788Ian Romanick                mWatchForAudioEOS = true;
57301f8de4a87157b01e8b9fe31c6766a15bbfb2788Ian Romanick            }
57401f8de4a87157b01e8b9fe31c6766a15bbfb2788Ian Romanick        } else {
57501f8de4a87157b01e8b9fe31c6766a15bbfb2788Ian Romanick            mAudioPlayer->resume();
576fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        }
577fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
578fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        postCheckAudioStatusEvent_l();
579fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    }
580fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
581fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    if (mTimeSource == NULL && mAudioPlayer == NULL) {
582fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        mTimeSource = new SystemTimeSource;
583fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    }
584f1ddca9f2143e377d2a70941dcedbb1f5c699e07Eric Anholt
585fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    if (mVideoSource != NULL) {
586fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        // Kick off video playback
587fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        postVideoEvent_l();
588fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    }
5893b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick
5903b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick    if (deferredAudioSeek) {
5913b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        // If there was a seek request while we were paused
5923b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        // and we're just starting up again, honor the request now.
5933b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        seekAudioIfNecessary_l();
594fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    }
595fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
5963b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick    if (mFlags & AT_EOS) {
5973b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        // Legacy behaviour, if a stream finishes playing and then
5983b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        // is started again, we play from the start...
5993b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        seekTo_l(0);
6003b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick    }
6013b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick
602fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick    return OK;
603fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick}
6043b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick
6053b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanickvoid AwesomePlayer::initRenderer_l() {
6063b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick    if (mISurface != NULL) {
6073b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        sp<MetaData> meta = mVideoSource->getFormat();
6083b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick
6093b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        int32_t format;
6103b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        const char *component;
6113b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        int32_t decodedWidth, decodedHeight;
6123b85f1cc6cb12e9d4931e12cf29adde578f389fdIan Romanick        CHECK(meta->findInt32(kKeyColorFormat, &format));
613fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        CHECK(meta->findCString(kKeyDecoderComponent, &component));
614fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
615fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick        CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
616fad607a9be59056aecda50176b4d20a8b5319747Ian Romanick
6173c033637de7def553559c11d037f2e8bbb750f77Kenneth Graunke        mVideoRenderer.clear();
618a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
619fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        // Must ensure that mVideoRenderer's destructor is actually executed
620a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        // before creating a new one.
6215a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick        IPCThreadState::self()->flushCommands();
6225a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6235a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick        if (!strncmp("OMX.", component, 4)) {
6245a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick            // Our OMX codecs allocate buffers on the media_server side
6255a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick            // therefore they require a remote IOMXRenderer that knows how
6265a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick            // to display them.
6275a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick            mVideoRenderer = new AwesomeRemoteRenderer(
6285a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick                mClient.interface()->createRenderer(
6295a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick                        mISurface, component,
6305a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick                        (OMX_COLOR_FORMATTYPE)format,
6318273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt                        decodedWidth, decodedHeight,
6324b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt                        mVideoWidth, mVideoHeight));
633fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke        } else {
634fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke            // Other decoders are instantiated locally and as a consequence
63578b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick            // allocate their buffers in local address space.
63678b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick            mVideoRenderer = new AwesomeLocalRenderer(
63778b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick                false,  // previewOnly
63878b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick                component,
63978b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick                (OMX_COLOR_FORMATTYPE)format,
6408895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick                mISurface,
6418895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick                mVideoWidth, mVideoHeight,
642cad9766118d269725ef33b4e9588d674d5225010Eric Anholt                decodedWidth, decodedHeight);
643cad9766118d269725ef33b4e9588d674d5225010Eric Anholt        }
644cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    }
645cad9766118d269725ef33b4e9588d674d5225010Eric Anholt}
646cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
647a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatus_t AwesomePlayer::pause() {
6485a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    Mutex::Autolock autoLock(mLock);
6495a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6505a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    mFlags &= ~CACHE_UNDERRUN;
6515a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6525a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    return pause_l();
6535a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick}
6545a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6555a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanickstatus_t AwesomePlayer::pause_l() {
6565a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    if (!(mFlags & PLAYING)) {
6575a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick        return OK;
6585a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    }
6595a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6605a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    cancelPlayerEvents(true /* keepBufferingGoing */);
6615a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6625a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    if (mAudioPlayer != NULL) {
6635a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick        mAudioPlayer->pause();
6645a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    }
6655a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6665a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    mFlags &= ~PLAYING;
667a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
6685a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    return OK;
6695a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick}
6705a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
671a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickbool AwesomePlayer::isPlaying() const {
6725a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
673a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
674a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
675a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickvoid AwesomePlayer::setISurface(const sp<ISurface> &isurface) {
676a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    Mutex::Autolock autoLock(mLock);
677fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke
678a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mISurface = isurface;
679a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
680a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
681a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickvoid AwesomePlayer::setAudioSink(
682fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke        const sp<MediaPlayerBase::AudioSink> &audioSink) {
6835a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    Mutex::Autolock autoLock(mLock);
6845a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6855a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    mAudioSink = audioSink;
6865a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick}
6875a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
6885a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanickstatus_t AwesomePlayer::setLooping(bool shouldLoop) {
6895a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    Mutex::Autolock autoLock(mLock);
6905a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
691b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt    mFlags = mFlags & ~LOOPING;
692b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt
693b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt    if (shouldLoop) {
694b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt        mFlags |= LOOPING;
695b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt    }
696b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt
697b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt    return OK;
698b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt}
6995a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
7005a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanickstatus_t AwesomePlayer::getDuration(int64_t *durationUs) {
701a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    Mutex::Autolock autoLock(mMiscStateLock);
702a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
7033b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke    if (mDurationUs < 0) {
704160d092507c1ca341b7c5c88e5ba94b4cf5fb7d0Eric Anholt        return UNKNOWN_ERROR;
7053b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke    }
706a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
707a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    *durationUs = mDurationUs;
708a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
709a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    return OK;
710a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
711a4b7b5a654ca810e296bb0cca1b27b8847f5548aKenneth Graunke
712a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatus_t AwesomePlayer::getPosition(int64_t *positionUs) {
713a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    if (mSeeking) {
71444d68fd06ff8b53fc70a9a07c897dda9b3457ef8Eric Anholt        *positionUs = mSeekTimeUs;
715bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt    } else if (mVideoSource != NULL) {
716bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt        Mutex::Autolock autoLock(mMiscStateLock);
71701665262e50162e858c45f92a8a7e12b953e56adEric Anholt        *positionUs = mVideoTimeUs;
71801665262e50162e858c45f92a8a7e12b953e56adEric Anholt    } else if (mAudioPlayer != NULL) {
719a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        *positionUs = mAudioPlayer->getMediaTimeUs();
720a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    } else {
721dc58b3f8ccd817fdee390a3df5b8e0fb29d5397cEric Anholt        *positionUs = 0;
722dc58b3f8ccd817fdee390a3df5b8e0fb29d5397cEric Anholt    }
723c2cb84e17b2f7a5db146faa9c9c2a2ffac4b6c19Eric Anholt
724c2cb84e17b2f7a5db146faa9c9c2a2ffac4b6c19Eric Anholt    return OK;
7256c86ea8adc095abeef7b3cd63d3321185542bf36Ian Romanick}
7265e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt
727a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatus_t AwesomePlayer::seekTo(int64_t timeUs) {
728a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    if (mExtractorFlags
729a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            & (MediaExtractor::CAN_SEEK_FORWARD
730a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick                | MediaExtractor::CAN_SEEK_BACKWARD)) {
731a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        Mutex::Autolock autoLock(mLock);
732a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        return seekTo_l(timeUs);
733a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    }
734a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
735d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt    return OK;
736d85d25dd1f4fd281bd210ba6ba5135ba1e3b535fKenneth Graunke}
737a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
738a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickstatus_t AwesomePlayer::seekTo_l(int64_t timeUs) {
73957e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke    if (mFlags & CACHE_UNDERRUN) {
74057e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke        mFlags &= ~CACHE_UNDERRUN;
74157e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke        play_l();
74257e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke    }
74357e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke
74457e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke    mSeeking = true;
745f2616e56de8a48360cae8f269727b58490555f4dIan Romanick    mSeekNotificationSent = false;
746f2616e56de8a48360cae8f269727b58490555f4dIan Romanick    mSeekTimeUs = timeUs;
74757e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke    mFlags &= ~AT_EOS;
74857e7da173e8d38bf0c95ded535cdf1b12a00a1a2Kenneth Graunke
749b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke    seekAudioIfNecessary_l();
750b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke
751b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke    if (!(mFlags & PLAYING)) {
752b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke        LOGV("seeking while paused, sending SEEK_COMPLETE notification"
753b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke             " immediately.");
754b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke
755b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke        notifyListener_l(MEDIA_SEEK_COMPLETE);
756b843c7a20c2d65494f30eb82622ae7db380f581aKenneth Graunke        mSeekNotificationSent = true;
7573a5ce85cfa4914711e56c8cf831699242618928eIan Romanick    }
7583a5ce85cfa4914711e56c8cf831699242618928eIan Romanick
759007f4881503b69055d65cfb20bd237673779786bKenneth Graunke    return OK;
760007f4881503b69055d65cfb20bd237673779786bKenneth Graunke}
761007f4881503b69055d65cfb20bd237673779786bKenneth Graunke
762007f4881503b69055d65cfb20bd237673779786bKenneth Graunkevoid AwesomePlayer::seekAudioIfNecessary_l() {
763007f4881503b69055d65cfb20bd237673779786bKenneth Graunke    if (mSeeking && mVideoSource == NULL && mAudioPlayer != NULL) {
764a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        mAudioPlayer->seekTo(mSeekTimeUs);
765a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
766a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        mWatchForAudioSeekComplete = true;
767a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        mWatchForAudioEOS = true;
7688a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt        mSeekNotificationSent = false;
7698a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt    }
7708a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt}
7718a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt
7728a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholtstatus_t AwesomePlayer::getVideoDimensions(
7738a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt        int32_t *width, int32_t *height) const {
7748a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt    Mutex::Autolock autoLock(mLock);
7758a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt
7768a1f186cc55979bb9df0a88b48da8d81460c3e7cEric Anholt    if (mVideoWidth < 0 || mVideoHeight < 0) {
777a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        return UNKNOWN_ERROR;
778a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    }
779a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
78014eea268284491d64ff92b37723bff1e9ff14b40Kenneth Graunke    *width = mVideoWidth;
78114eea268284491d64ff92b37723bff1e9ff14b40Kenneth Graunke    *height = mVideoHeight;
782a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
783a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    return OK;
784a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
785a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
786a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickvoid AwesomePlayer::setAudioSource(sp<MediaSource> source) {
787a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    CHECK(source != NULL);
7884dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri
7894dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri    mAudioTrack = source;
790832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt}
791832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt
792832aad989e3d319a8aaac046aa49df25da134d82Eric Anholtstatus_t AwesomePlayer::initAudioDecoder() {
793832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt    sp<MetaData> meta = mAudioTrack->getFormat();
7944dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri
795832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt    const char *mime;
796832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt    CHECK(meta->findCString(kKeyMIMEType, &mime));
797832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt
798832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
7994dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri        mAudioSource = mAudioTrack;
800a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    } else {
801a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        mAudioSource = OMXCodec::Create(
802a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick                mClient.interface(), mAudioTrack->getFormat(),
803a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick                false, // createEncoder
804a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick                mAudioTrack);
805a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    }
806a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
807a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    if (mAudioSource != NULL) {
808a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        int64_t durationUs;
809a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
810a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            Mutex::Autolock autoLock(mMiscStateLock);
811a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            if (mDurationUs < 0 || durationUs > mDurationUs) {
812a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick                mDurationUs = durationUs;
813a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            }
814a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        }
815a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
816a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        status_t err = mAudioSource->start();
817a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
818a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        if (err != OK) {
819a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            mAudioSource.clear();
820a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            return err;
821007f4881503b69055d65cfb20bd237673779786bKenneth Graunke        }
822007f4881503b69055d65cfb20bd237673779786bKenneth Graunke    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
823007f4881503b69055d65cfb20bd237673779786bKenneth Graunke        // For legacy reasons we're simply going to ignore the absence
824007f4881503b69055d65cfb20bd237673779786bKenneth Graunke        // of an audio decoder for QCELP instead of aborting playback
825007f4881503b69055d65cfb20bd237673779786bKenneth Graunke        // altogether.
826007f4881503b69055d65cfb20bd237673779786bKenneth Graunke        return OK;
827007f4881503b69055d65cfb20bd237673779786bKenneth Graunke    }
82811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick
82911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick    return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
830007f4881503b69055d65cfb20bd237673779786bKenneth Graunke}
831007f4881503b69055d65cfb20bd237673779786bKenneth Graunke
832007f4881503b69055d65cfb20bd237673779786bKenneth Graunkevoid AwesomePlayer::setVideoSource(sp<MediaSource> source) {
833007f4881503b69055d65cfb20bd237673779786bKenneth Graunke    CHECK(source != NULL);
834a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
835a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mVideoTrack = source;
836fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke}
837a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
83813f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanickstatus_t AwesomePlayer::initVideoDecoder() {
83913f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick    mVideoSource = OMXCodec::Create(
84013f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick            mClient.interface(), mVideoTrack->getFormat(),
84113f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick            false, // createEncoder
84213f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick            mVideoTrack);
84313f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick
84413f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick    if (mVideoSource != NULL) {
84513f57d42b6929f50d8ef8b4123f46a61c46fde7bIan Romanick        int64_t durationUs;
846a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
847fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke            Mutex::Autolock autoLock(mMiscStateLock);
848a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            if (mDurationUs < 0 || durationUs > mDurationUs) {
84911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick                mDurationUs = durationUs;
85011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick            }
85111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick        }
85211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick
85311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick        CHECK(mVideoTrack->getFormat()->findInt32(kKeyWidth, &mVideoWidth));
85411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick        CHECK(mVideoTrack->getFormat()->findInt32(kKeyHeight, &mVideoHeight));
8556d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
8566d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt        status_t err = mVideoSource->start();
8576d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt
8586d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt        if (err != OK) {
8596d8a0a0aadaafbab02dffcf7f89eb0210dd37b2eEric Anholt            mVideoSource.clear();
8608273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt            return err;
8614b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt        }
862e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    }
863e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
864e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
865e053d62aa573651abdd78666d299272c8219a3aaIan Romanick}
866e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
867e053d62aa573651abdd78666d299272c8219a3aaIan Romanickvoid AwesomePlayer::onVideoEvent() {
868fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke    Mutex::Autolock autoLock(mLock);
869fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke    if (!mVideoEventPending) {
870e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        // The event has been cancelled in reset_l() but had already
871e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        // been scheduled for execution at that time.
872e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        return;
8737dd6adbe2e791b22de97175a8715ef1217619c99Kenneth Graunke    }
874e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    mVideoEventPending = false;
875e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
876e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    if (mSeeking) {
877e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        if (mLastVideoBuffer) {
8784b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt            mLastVideoBuffer->release();
8797dd6adbe2e791b22de97175a8715ef1217619c99Kenneth Graunke            mLastVideoBuffer = NULL;
88011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick        }
88111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick
8827dd6adbe2e791b22de97175a8715ef1217619c99Kenneth Graunke        if (mVideoBuffer) {
883160d092507c1ca341b7c5c88e5ba94b4cf5fb7d0Eric Anholt            mVideoBuffer->release();
8843b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke            mVideoBuffer = NULL;
8853b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke        }
8863b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke
8873b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke        if (mCachedSource != NULL && mAudioSource != NULL) {
8883b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke            // We're going to seek the video source first, followed by
8893b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke            // the audio source.
890351525d534268b08c090f9ce42a67e9329a969aeIan Romanick            // In order to avoid jumps in the DataSource offset caused by
891351525d534268b08c090f9ce42a67e9329a969aeIan Romanick            // the audio codec prefetching data from the old locations
892351525d534268b08c090f9ce42a67e9329a969aeIan Romanick            // while the video codec is already reading data from the new
893351525d534268b08c090f9ce42a67e9329a969aeIan Romanick            // locations, we'll "pause" the audio source, causing it to
894351525d534268b08c090f9ce42a67e9329a969aeIan Romanick            // stop reading input data until a subsequent seek.
895351525d534268b08c090f9ce42a67e9329a969aeIan Romanick
8963b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke            if (mAudioPlayer != NULL) {
8973b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke                mAudioPlayer->pause();
8983b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke            }
8993b96996b7eb6e3603a5f138177867c3e856e0dfaKenneth Graunke            mAudioSource->pause();
90078b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick        }
90178b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    }
90278b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick
90378b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick    if (!mVideoBuffer) {
90478b51b0fdd61b58940f9043ef9046217552f2c70Ian Romanick        MediaSource::ReadOptions options;
9058895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick        if (mSeeking) {
9068895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick            LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
907a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
90811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick            options.setSeekTo(mSeekTimeUs);
909a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        }
910a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        for (;;) {
911a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            status_t err = mVideoSource->read(&mVideoBuffer, &options);
912ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick            options.clearSeekTo();
913ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
914ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick            if (err != OK) {
915fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke                CHECK_EQ(mVideoBuffer, NULL);
916ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
9171f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt                if (err == INFO_FORMAT_CHANGED) {
918b427c917ce47675b102fac3ddace883629ff6be8Ian Romanick                    LOGV("VideoSource signalled format change.");
919ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
920d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt                    if (mVideoRenderer != NULL) {
9219e7c34b865309c65ea5a763900e2d0eae4b58ce5Ian Romanick                        mVideoRendererIsPreview = false;
9229e7c34b865309c65ea5a763900e2d0eae4b58ce5Ian Romanick                        initRenderer_l();
923471471f83471481db0445e73f8c89e6a9149838eIan Romanick                    }
924ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick                    continue;
925ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick                }
9268273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
9274b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt                postStreamDoneEvent_l(err);
928fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke                return;
929fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke            }
930cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
931cad9766118d269725ef33b4e9588d674d5225010Eric Anholt            if (mVideoBuffer->range_length() == 0) {
932cad9766118d269725ef33b4e9588d674d5225010Eric Anholt                // Some decoders, notably the PV AVC software decoder
933cad9766118d269725ef33b4e9588d674d5225010Eric Anholt                // return spurious empty buffers that we just want to ignore.
934cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
935ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick                mVideoBuffer->release();
936ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick                mVideoBuffer = NULL;
937ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick                continue;
938ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick            }
939ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
9408895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick            break;
9418895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick        }
942ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick    }
943ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
944e01193af325cbdde51b3219c85c58f19d5a87f1bCarl Worth    int64_t timeUs;
945e01193af325cbdde51b3219c85c58f19d5a87f1bCarl Worth    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
946ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
947e01193af325cbdde51b3219c85c58f19d5a87f1bCarl Worth    {
948ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick        Mutex::Autolock autoLock(mMiscStateLock);
9499878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick        mVideoTimeUs = timeUs;
9509878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick    }
9519878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick
9529878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick    if (mSeeking) {
9539878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick        if (mAudioPlayer != NULL) {
9549878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick            LOGV("seeking audio to %lld us (%.2f secs).", timeUs, timeUs / 1E6);
9559878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick
9569878c6518f7938bd5fdae22265dd30bc72d7343cIan Romanick            mAudioPlayer->seekTo(timeUs);
95793614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick            mAudioPlayer->resume();
95893614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick            mWatchForAudioSeekComplete = true;
95993614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick            mWatchForAudioEOS = true;
96093614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick        } else if (!mSeekNotificationSent) {
96193614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick            // If we're playing video only, report seek complete now,
9620f0ea5826454cf25d6e76ac848a317e673ff1032Ian Romanick            // otherwise audio player will notify us later.
96393614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick            notifyListener_l(MEDIA_SEEK_COMPLETE);
96493614bc4b971bb59824179057a4bfa7aac383ce3Ian Romanick        }
965e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
966e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        mFlags |= FIRST_FRAME;
967e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        mSeeking = false;
9681f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt        mSeekNotificationSent = false;
969cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    }
970cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
971cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    if (mFlags & FIRST_FRAME) {
972cad9766118d269725ef33b4e9588d674d5225010Eric Anholt        mFlags &= ~FIRST_FRAME;
973cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
974792e01c1e259077eb339af3ce61905fd227ae4bdIan Romanick        mTimeSourceDeltaUs = mTimeSource->getRealTimeUs() - timeUs;
975792e01c1e259077eb339af3ce61905fd227ae4bdIan Romanick    }
9761f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt
977792e01c1e259077eb339af3ce61905fd227ae4bdIan Romanick    int64_t realTimeUs, mediaTimeUs;
978792e01c1e259077eb339af3ce61905fd227ae4bdIan Romanick    if (mAudioPlayer != NULL
979cad9766118d269725ef33b4e9588d674d5225010Eric Anholt        && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
980cad9766118d269725ef33b4e9588d674d5225010Eric Anholt        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
981cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    }
982cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
983cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    int64_t nowUs = mTimeSource->getRealTimeUs() - mTimeSourceDeltaUs;
984a48a2b66e86d6d1c2fbb24bc60df2fdef42b3086Ian Romanick
985a48a2b66e86d6d1c2fbb24bc60df2fdef42b3086Ian Romanick    int64_t latenessUs = nowUs - timeUs;
986a48a2b66e86d6d1c2fbb24bc60df2fdef42b3086Ian Romanick
987ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick    if (latenessUs > 40000) {
988471471f83471481db0445e73f8c89e6a9149838eIan Romanick        // We're more than 40ms late.
989b427c917ce47675b102fac3ddace883629ff6be8Ian Romanick        LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);
990471471f83471481db0445e73f8c89e6a9149838eIan Romanick
991d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        mVideoBuffer->release();
992471471f83471481db0445e73f8c89e6a9149838eIan Romanick        mVideoBuffer = NULL;
993471471f83471481db0445e73f8c89e6a9149838eIan Romanick
9941f47245bdda2c85bf0f0174e6c24a50486b413aaEric Anholt        postVideoEvent_l();
995ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick        return;
996ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick    }
997ed45ec6a515f3529f12fc23d51621e435d3b6cdfIan Romanick
9989578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    if (latenessUs < -10000) {
9999578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        // We're more than 10ms early.
10009578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10019578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        postVideoEvent_l(10000);
10029578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        return;
10039578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    }
10049578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10059578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
10069578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        mVideoRendererIsPreview = false;
10079578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
1008d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        initRenderer_l();
10099578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    }
10109578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10119578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    if (mVideoRenderer != NULL) {
10129578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        mVideoRenderer->render(mVideoBuffer);
10139578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    }
10149578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10159578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    if (mLastVideoBuffer) {
10169578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        mLastVideoBuffer->release();
1017d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        mLastVideoBuffer = NULL;
10189578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    }
10199578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    mLastVideoBuffer = mVideoBuffer;
1020fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    mVideoBuffer = NULL;
10219578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10229578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    postVideoEvent_l();
1023d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt}
10249578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10259578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanickvoid AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
10268273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt    if (mVideoEventPending) {
10274b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt        return;
1028cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    }
1029cad9766118d269725ef33b4e9588d674d5225010Eric Anholt
1030cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    mVideoEventPending = true;
1031cad9766118d269725ef33b4e9588d674d5225010Eric Anholt    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
1032cad9766118d269725ef33b4e9588d674d5225010Eric Anholt}
1033fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke
10349578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanickvoid AwesomePlayer::postStreamDoneEvent_l(status_t status) {
10359578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    if (mStreamDoneEventPending) {
10369578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        return;
10379578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    }
10389578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    mStreamDoneEventPending = true;
10399578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick
10409578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    mStreamDoneStatus = status;
10419578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    mQueue.postEvent(mStreamDoneEvent);
10429578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick}
10438895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick
10448895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanickvoid AwesomePlayer::postBufferingEvent_l() {
1045fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    if (mBufferingEventPending) {
10469578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick        return;
1047f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    }
1048f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    mBufferingEventPending = true;
1049f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
1050f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick}
1051f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
1052f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanickvoid AwesomePlayer::postCheckAudioStatusEvent_l() {
1053f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    if (mAudioStatusEventPending) {
1054f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        return;
1055f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    }
1056f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    mAudioStatusEventPending = true;
1057f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    mQueue.postEventWithDelay(mCheckAudioStatusEvent, 100000ll);
1058f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick}
1059f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
1060f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanickvoid AwesomePlayer::onCheckAudioStatus() {
1061f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    Mutex::Autolock autoLock(mLock);
1062f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    if (!mAudioStatusEventPending) {
1063f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        // Event was dispatched and while we were blocking on the mutex,
10644b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt        // has already been cancelled.
1065f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        return;
1066d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    }
10670c005bd773784ee5feb2ee3d7d00c2c4335eafb4Eric Anholt
10680c005bd773784ee5feb2ee3d7d00c2c4335eafb4Eric Anholt    mAudioStatusEventPending = false;
1069f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
1070f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
10718273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt        mWatchForAudioSeekComplete = false;
10724b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt
1073f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        if (!mSeekNotificationSent) {
1074f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick            notifyListener_l(MEDIA_SEEK_COMPLETE);
1075f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick            mSeekNotificationSent = true;
1076f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        }
1077f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
10788895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick        mSeeking = false;
10798895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick    }
1080f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
1081f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    status_t finalStatus;
1082f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
1083f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        mWatchForAudioEOS = false;
1084f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick        postStreamDoneEvent_l(finalStatus);
1085f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    }
1086f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
1087f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    postCheckAudioStatusEvent_l();
1088f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick}
1089f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick
1090f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanickstatus_t AwesomePlayer::prepare() {
1091f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanick    Mutex::Autolock autoLock(mLock);
10920c005bd773784ee5feb2ee3d7d00c2c4335eafb4Eric Anholt    return prepare_l();
10930c005bd773784ee5feb2ee3d7d00c2c4335eafb4Eric Anholt}
10940c005bd773784ee5feb2ee3d7d00c2c4335eafb4Eric Anholt
1095f8e31e00b1078dc28187a43a1ab8949e154e7533Ian Romanickstatus_t AwesomePlayer::prepare_l() {
109616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    if (mFlags & PREPARED) {
109716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke        return OK;
109816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    }
109916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
110016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    if (mFlags & PREPARING) {
110116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke        return UNKNOWN_ERROR;
110216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    }
110316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
1104d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt    mIsAsyncPrepare = false;
110516efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    status_t err = prepareAsync_l();
110616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
110716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    if (err != OK) {
110816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke        return err;
110916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    }
111084ee01f40acf88185484df386b7715034e7685c9Aras Pranckevicius
111116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    while (mFlags & PREPARING) {
111216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke        mPreparedCondition.wait(mLock);
111316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    }
11148273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
111516efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    return mPrepareResult;
111616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke}
111716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
111816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkestatus_t AwesomePlayer::prepareAsync() {
111916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    Mutex::Autolock autoLock(mLock);
112016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
112116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    if (mFlags & PREPARING) {
112216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke        return UNKNOWN_ERROR;  // async prepare already pending
112316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke    }
112416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
11259578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    mIsAsyncPrepare = true;
11269578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick    return prepareAsync_l();
11279578c87ce23a98472d52f15b0a7063f4df036c4dIan Romanick}
112881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
112981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanickstatus_t AwesomePlayer::prepareAsync_l() {
113081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    if (mFlags & PREPARING) {
113181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        return UNKNOWN_ERROR;  // async prepare already pending
1132e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    }
1133e053d62aa573651abdd78666d299272c8219a3aaIan Romanick
1134e053d62aa573651abdd78666d299272c8219a3aaIan Romanick    if (!mQueueStarted) {
1135e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        mQueue.start();
1136e053d62aa573651abdd78666d299272c8219a3aaIan Romanick        mQueueStarted = true;
113781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    }
113881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
113981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    mFlags |= PREPARING;
114081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    mAsyncPrepareEvent = new AwesomeEvent(
114181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            this, &AwesomePlayer::onPrepareAsyncEvent);
114281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
114381377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    mQueue.postEvent(mAsyncPrepareEvent);
114481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
114581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    return OK;
114681377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick}
114781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
114881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanickstatus_t AwesomePlayer::finishSetDataSource_l() {
114981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    sp<DataSource> dataSource;
115081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
115181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    if (!strncasecmp("http://", mUri.string(), 7)) {
115281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        mConnectingDataSource = new NuHTTPDataSource;
115381377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
115481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        mLock.unlock();
115581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        status_t err = mConnectingDataSource->connect(mUri/*, mUriHeaders */);
115681377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        mLock.lock();
115781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
115881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        if (err != OK) {
115981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            mConnectingDataSource.clear();
116081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
1161b97efa5db5fce2e0d9a4c61a939c85b240c89170Kenneth Graunke            LOGI("mConnectingDataSource->connect() returned %d", err);
116281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            return err;
1163d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt        }
116481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
116581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick#if 0
11668273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt        mCachedSource = new NuCachedSource2(
11674b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt                new ThrottledSource(
1168fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke                    mConnectingDataSource, 50 * 1024 /* bytes/sec */));
1169fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke#else
117026d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke        mCachedSource = new NuCachedSource2(mConnectingDataSource);
117126d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke#endif
117226d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke        mConnectingDataSource.clear();
117326d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke
117426d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke        dataSource = mCachedSource;
117526d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke    } else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
117626d74cd1d140786b8f4b1ccbaf500a16e68eec3cKenneth Graunke        String8 uri("http://");
1177c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke        uri.append(mUri.string() + 11);
1178c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke
1179c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke        dataSource = new LiveSource(uri.string());
1180c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke
1181c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke        mCachedSource = new NuCachedSource2(dataSource);
118256d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke        dataSource = mCachedSource;
118356d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke
118456d3f6ad782e9819b40544494826954d3fcf978bKenneth Graunke        sp<MediaExtractor> extractor =
1185c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke            MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
1186c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke
1187c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke        return setDataSource_l(extractor);
1188c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke    } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
1189c30f6e5dea7e75983784f3539304c8dd36356d1cKenneth Graunke        if (mLooper == NULL) {
119081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            mLooper = new ALooper;
119181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            mLooper->start();
119281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        }
119381377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        mRTSPController = new ARTSPController(mLooper);
119481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        status_t err = mRTSPController->connect(mUri.string());
119581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
119681377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        LOGI("ARTSPController::connect returned %d", err);
119781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
119881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        if (err != OK) {
119981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            mRTSPController.clear();
120081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick            return err;
120181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        }
120281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
120381377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        sp<MediaExtractor> extractor = mRTSPController.get();
120481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        return setDataSource_l(extractor);
120581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    } else {
120681377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
120781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    }
120881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
120981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    if (dataSource == NULL) {
121081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        return UNKNOWN_ERROR;
121181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    }
121281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
121381377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
121481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
121581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    if (extractor == NULL) {
121681377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        return UNKNOWN_ERROR;
121781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    }
121881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
121981377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    return setDataSource_l(extractor);
122081377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick}
122181377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
122281377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanickvoid AwesomePlayer::abortPrepare(status_t err) {
122381377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    CHECK(err != OK);
122481377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
122581377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    if (mIsAsyncPrepare) {
122681377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick        notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
122781377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick    }
122881377c012cf5db3efe2e39885846c60b6e5c6eb8Ian Romanick
1229a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mPrepareResult = err;
1230a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mFlags &= ~(PREPARING|PREPARE_CANCELLED);
1231a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mAsyncPrepareEvent = NULL;
1232a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    mPreparedCondition.broadcast();
1233a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
1234a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
1235a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick// static
1236a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickbool AwesomePlayer::ContinuePreparation(void *cookie) {
1237a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
1238f25a5ad93961c335b56d4f0508cc5c00b77ee519Kenneth Graunke
1239a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    return (me->mFlags & PREPARE_CANCELLED) == 0;
1240a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick}
1241a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
1242a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanickvoid AwesomePlayer::onPrepareAsyncEvent() {
1243a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    {
1244a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        Mutex::Autolock autoLock(mLock);
1245a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
1246a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick        if (mFlags & PREPARE_CANCELLED) {
1247a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick            LOGI("prepare was cancelled before doing anything");
1248affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke            abortPrepare(UNKNOWN_ERROR);
1249affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke            return;
1250affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke        }
1251affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke
1252affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke        if (mUri.size() > 0) {
12536315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick            status_t err = finishSetDataSource_l();
12546315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick
12556315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick            if (err != OK) {
125605a4e59c2410292f595cfe0cc552a86ae69b20d2Eric Anholt                abortPrepare(err);
1257cad9766118d269725ef33b4e9588d674d5225010Eric Anholt                return;
12588273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt            }
12594b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt        }
1260fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke
1261fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke        if (mVideoTrack != NULL && mVideoSource == NULL) {
12627d21104a8b92c139051e9a224c5d863802a8ade6Eric Anholt            status_t err = initVideoDecoder();
12637d21104a8b92c139051e9a224c5d863802a8ade6Eric Anholt
12647d21104a8b92c139051e9a224c5d863802a8ade6Eric Anholt            if (err != OK) {
12657d21104a8b92c139051e9a224c5d863802a8ade6Eric Anholt                abortPrepare(err);
12667d21104a8b92c139051e9a224c5d863802a8ade6Eric Anholt                return;
1267affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke            }
1268affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke        }
1269affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke
1270affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke        if (mAudioTrack != NULL && mAudioSource == NULL) {
1271affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke            status_t err = initAudioDecoder();
1272affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke
1273affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke            if (err != OK) {
1274affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke                abortPrepare(err);
1275affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke                return;
1276affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke            }
12778895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick        }
12788895bae55ba8d9f62dd59cbd924ac37c8a7dcdb1Ian Romanick    }
1279affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke
1280affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke    Mutex::Autolock autoLock(mLock);
1281a9fafc6504ebccdc0fee3d2529c3fe6068cc86b8Eric Anholt
1282affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke    if (mIsAsyncPrepare) {
1283affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke        if (mVideoWidth < 0 || mVideoHeight < 0) {
12842b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
12852b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick        } else {
12862b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick            notifyListener_l(MEDIA_SET_VIDEO_SIZE, mVideoWidth, mVideoHeight);
12872b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick        }
12882b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick
1289affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke        notifyListener_l(MEDIA_PREPARED);
1290affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke    }
12916315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick
12926315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick    mPrepareResult = OK;
12936315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick    mFlags &= ~(PREPARING|PREPARE_CANCELLED);
12946315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick    mFlags |= PREPARED;
12956315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick    mAsyncPrepareEvent = NULL;
12966315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick    mPreparedCondition.broadcast();
12976315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick
12986315b68f5fbe529bce3497b67c42af1eaa62b8c1Ian Romanick    postBufferingEvent_l();
1299affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke}
1300affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunke
1301affc1413ac9f1f077a4ba1a1b7135f73d7a71167Kenneth Graunkestatus_t AwesomePlayer::suspend() {
1302fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke    LOGV("suspend");
1303a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick    Mutex::Autolock autoLock(mLock);
13048273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
1305ca088cc277ce9f986693c857f3961dc0e1a4d91cIan Romanick    if (mSuspensionState != NULL) {
130644e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke        if (mLastVideoBuffer == NULL) {
130744e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke            //go into here if video is suspended again
130844e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke            //after resuming without being played between
130944e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke            //them
131044e1dfa2df4de3e2de963f0505cdadade6fe8180Kenneth Graunke            SuspensionState *state = mSuspensionState;
1311c7da28b4beb3a593f49a6c01a90b123584b421e8Eric Anholt            mSuspensionState = NULL;
1312fb9fb5f51deca28ed1ec7b71759fb71fc26a0ab6Kenneth Graunke            reset_l();
13132b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick            mSuspensionState = state;
13142b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick            return OK;
13152b3c476fa08e33a0ee1633b173a7df31ecaca582Ian Romanick        }
131670fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
131770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        delete mSuspensionState;
131870fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        mSuspensionState = NULL;
131970fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    }
132070fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
132170fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    if (mFlags & PREPARING) {
132270fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        mFlags |= PREPARE_CANCELLED;
132370fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        if (mConnectingDataSource != NULL) {
13248273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt            LOGI("interrupting the connection process");
13258273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt            mConnectingDataSource->disconnect();
13264b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt        }
1327fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke    }
1328fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke
1329d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    while (mFlags & PREPARING) {
1330d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt        mPreparedCondition.wait(mLock);
1331d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    }
1332d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1333d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    SuspensionState *state = new SuspensionState;
133470fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    state->mUri = mUri;
133570fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    state->mUriHeaders = mUriHeaders;
133670fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    state->mFileSource = mFileSource;
133770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
133870fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    state->mFlags = mFlags & (PLAYING | LOOPING | AT_EOS);
133936ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick    getPosition(&state->mPositionUs);
134070fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
1341f3a002b503542fe2544025c6a42d552fdc4907c2Ian Romanick    if (mLastVideoBuffer) {
1342b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick        size_t size = mLastVideoBuffer->range_length();
1343b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick        if (size) {
1344b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            state->mLastVideoFrameSize = size;
1345b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            state->mLastVideoFrame = malloc(size);
1346b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            memcpy(state->mLastVideoFrame,
1347b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                   (const uint8_t *)mLastVideoBuffer->data()
1348b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                        + mLastVideoBuffer->range_offset(),
1349b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick                   size);
1350b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick
1351b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            state->mVideoWidth = mVideoWidth;
1352b067db2e253059e83249b1e4d5f3c626b0e33807Ian Romanick            state->mVideoHeight = mVideoHeight;
1353c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick
1354c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick            sp<MetaData> meta = mVideoSource->getFormat();
1355c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick            CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat));
1356c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick            CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth));
1357c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick            CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight));
1358f3a002b503542fe2544025c6a42d552fdc4907c2Ian Romanick        }
135936ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick    }
136036ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick
136136ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick    reset_l();
136236ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick
136336ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick    mSuspensionState = state;
136470fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
136570fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    return OK;
136670fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick}
136770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
136870fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanickstatus_t AwesomePlayer::resume() {
136970fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    LOGV("resume");
137070fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    Mutex::Autolock autoLock(mLock);
137170fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
137270fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    if (mSuspensionState == NULL) {
13738273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt        return INVALID_OPERATION;
13748273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt    }
13754b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt
1376fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke    SuspensionState *state = mSuspensionState;
1377fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke    mSuspensionState = NULL;
1378b145e903694fa932ab1e0d955e889555193ab604Eric Anholt
1379b145e903694fa932ab1e0d955e889555193ab604Eric Anholt    status_t err;
1380b145e903694fa932ab1e0d955e889555193ab604Eric Anholt    if (state->mFileSource != NULL) {
1381b145e903694fa932ab1e0d955e889555193ab604Eric Anholt        err = setDataSource_l(state->mFileSource);
1382b145e903694fa932ab1e0d955e889555193ab604Eric Anholt
138370fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        if (err == OK) {
138470fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick            mFileSource = state->mFileSource;
138570fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        }
138670fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    } else {
138770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        err = setDataSource_l(state->mUri, &state->mUriHeaders);
138836ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick    }
138970fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
139070fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    if (err != OK) {
1391c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick        delete state;
1392c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick        state = NULL;
1393c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick
1394c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick        return err;
1395c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick    }
1396f3a002b503542fe2544025c6a42d552fdc4907c2Ian Romanick
139770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    seekTo_l(state->mPositionUs);
139836ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick
139936ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick    mFlags = state->mFlags & (LOOPING | AT_EOS);
140036ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick
140170fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    if (state->mLastVideoFrame && mISurface != NULL) {
140270fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        mVideoRenderer =
140370fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick            new AwesomeLocalRenderer(
140470fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    true,  // previewOnly
140570fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    "",
140670fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    (OMX_COLOR_FORMATTYPE)state->mColorFormat,
140770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    mISurface,
140870fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    state->mVideoWidth,
140970fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    state->mVideoHeight,
141070fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    state->mDecodedWidth,
141170fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick                    state->mDecodedHeight);
14128273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt
14138273bd46877e2ea2b8a02b87a11c68102d07e1f2Eric Anholt        mVideoRendererIsPreview = true;
14144b6fd39c89f308a379882426c1ed3616d60c4628Eric Anholt
1415fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke        ((AwesomeLocalRenderer *)mVideoRenderer.get())->render(
1416fb2ffd2846b48cb50128fb74df56f2ee63179832Kenneth Graunke                state->mLastVideoFrame, state->mLastVideoFrameSize);
141770fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    }
141870fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick
141970fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    if (state->mFlags & PLAYING) {
142070fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick        play_l();
142170fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    }
142236ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick
142370fe8b66632f4afd87ebb12a450b1e639428e88fIan Romanick    mSuspensionState = state;
1424f3a002b503542fe2544025c6a42d552fdc4907c2Ian Romanick    state = NULL;
1425c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick
1426c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick    return OK;
1427c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick}
1428c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanick
1429c7b1046a9fa6da916f11fb9e43d61fd772470183Ian Romanickuint32_t AwesomePlayer::flags() const {
1430f3a002b503542fe2544025c6a42d552fdc4907c2Ian Romanick    return mExtractorFlags;
143136ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick}
143236ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick
143336ea28646c666ac2af9b43c47e65f9f53ffcc390Ian Romanick}  // namespace android
1434a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick
1435a87ac255cf7ef0672b4de865d82e6a40c93b57dIan Romanick