AwesomePlayer.cpp revision 49c59815369616b0fd5451ccabd377e8fe1dc3fa
1bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber/*
2bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber *
4bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * you may not use this file except in compliance with the License.
6bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * You may obtain a copy of the License at
7bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber *
8bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber *
10bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Unless required by applicable law or agreed to in writing, software
11bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * See the License for the specific language governing permissions and
14bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * limitations under the License.
15bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber */
16bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
176c00983982d167bdb348c437f0480a480f38696cGlenn Kasten#undef DEBUG_HDCP
18eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten
19bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber//#define LOG_NDEBUG 0
20bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#define LOG_TAG "AwesomePlayer"
21bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <utils/Log.h>
22bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
23988e3f0b2c74095deae580157c57935a98573052Andreas Huber#include <dlfcn.h>
24988e3f0b2c74095deae580157c57935a98573052Andreas Huber
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "include/ARTSPController.h"
26bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include "include/AwesomePlayer.h"
27681755fc0d0797506456f46a2a10555916d6be32Andreas Huber#include "include/DRMExtractor.h"
28733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber#include "include/SoftwareRenderer.h"
290a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#include "include/NuCachedSource2.h"
300a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#include "include/ThrottledSource.h"
31bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber#include "include/MPEG2TSExtractor.h"
32681755fc0d0797506456f46a2a10555916d6be32Andreas Huber#include "include/WVMExtractor.h"
33bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
34965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include "timedtext/TimedTextPlayer.h"
35965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
364844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber#include <binder/IPCThreadState.h>
377cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang#include <binder/IServiceManager.h>
387cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang#include <media/IMediaPlayerService.h>
39e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/hexdump.h>
40e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/ADebug.h>
41bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/AudioPlayer.h>
42bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/DataSource.h>
43bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/FileSource.h>
44bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MediaBuffer.h>
45717826ececd8d39596f62418677721d70776add1Andreas Huber#include <media/stagefright/MediaDefs.h>
46bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MediaExtractor.h>
47bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MediaSource.h>
48bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MetaData.h>
49bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/OMXCodec.h>
50717826ececd8d39596f62418677721d70776add1Andreas Huber
515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <surfaceflinger/Surface.h>
521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h>
531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/SurfaceTextureClient.h>
542eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten#include <surfaceflinger/ISurfaceComposer.h>
553cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ALooper.h>
5714acc736e336cbd6026df781d4f411e908831815Andreas Huber#include <media/stagefright/foundation/AMessage.h>
58e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber
59eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#include <cutils/properties.h>
60eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten
61e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber#define USE_SURFACE_ALLOC 1
6214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong#define FRAME_DROP_FREQ 0
63e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber
64bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubernamespace android {
65bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
668650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huberstatic int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
6783ed9d41b5aea53a5f3f0ae2fa14e101c079a12aGloria Wangstatic int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
68100a4408968b90e314526185d572c72ea4cc784aAndreas Huberstatic int64_t kHighWaterMarkRTSPUs = 4000000ll;  // 4secs
69ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huberstatic const size_t kLowWaterMarkBytes = 40000;
70ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huberstatic const size_t kHighWaterMarkBytes = 200000;
718650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
72bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstruct AwesomeEvent : public TimedEventQueue::Event {
73c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    AwesomeEvent(
74c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            AwesomePlayer *player,
75c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            void (AwesomePlayer::*method)())
76bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        : mPlayer(player),
77c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber          mMethod(method) {
78bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
79bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
80bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberprotected:
81bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    virtual ~AwesomeEvent() {}
82bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
83bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
84c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber        (mPlayer->*mMethod)();
85bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
86bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
87bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberprivate:
88bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    AwesomePlayer *mPlayer;
89c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    void (AwesomePlayer::*mMethod)();
90bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
91bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    AwesomeEvent(const AwesomeEvent &);
92bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    AwesomeEvent &operator=(const AwesomeEvent &);
93bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber};
94bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
95733b7729ea462fae9c6899456444e28fef1c757cAndreas Huberstruct AwesomeLocalRenderer : public AwesomeRenderer {
96733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    AwesomeLocalRenderer(
971173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
981173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
99733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    }
100733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
101733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    virtual void render(MediaBuffer *buffer) {
102fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber        render((const uint8_t *)buffer->data() + buffer->range_offset(),
103fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber               buffer->range_length());
104fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber    }
105fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber
106fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber    void render(const void *data, size_t size) {
107fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber        mTarget->render(data, size, NULL);
108733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    }
109733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
110733b7729ea462fae9c6899456444e28fef1c757cAndreas Huberprotected:
111733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    virtual ~AwesomeLocalRenderer() {
112733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber        delete mTarget;
113733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber        mTarget = NULL;
114733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    }
115733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
116733b7729ea462fae9c6899456444e28fef1c757cAndreas Huberprivate:
1170a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    SoftwareRenderer *mTarget;
118988e3f0b2c74095deae580157c57935a98573052Andreas Huber
119733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    AwesomeLocalRenderer(const AwesomeLocalRenderer &);
120733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
121733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber};
122733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
1236a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennisstruct AwesomeNativeWindowRenderer : public AwesomeRenderer {
124ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    AwesomeNativeWindowRenderer(
125ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            const sp<ANativeWindow> &nativeWindow,
126ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            int32_t rotationDegrees)
1276a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        : mNativeWindow(nativeWindow) {
128ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        applyRotation(rotationDegrees);
1296a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    }
1306a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1316a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    virtual void render(MediaBuffer *buffer) {
132593e2773f616a926af45e74359e21a898c89875fGlenn Kasten        int64_t timeUs;
133593e2773f616a926af45e74359e21a898c89875fGlenn Kasten        CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
134593e2773f616a926af45e74359e21a898c89875fGlenn Kasten        native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
1356a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        status_t err = mNativeWindow->queueBuffer(
1366a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis                mNativeWindow.get(), buffer->graphicBuffer().get());
1376a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        if (err != 0) {
1386a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis            LOGE("queueBuffer failed with error %s (%d)", strerror(-err),
1396a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis                    -err);
1406a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis            return;
1416a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        }
1426a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1436a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        sp<MetaData> metaData = buffer->meta_data();
1446a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        metaData->setInt32(kKeyRendered, 1);
1456a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    }
1466a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1476a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennisprotected:
1486a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    virtual ~AwesomeNativeWindowRenderer() {}
1496a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1506a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennisprivate:
1516a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    sp<ANativeWindow> mNativeWindow;
1526a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
153ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    void applyRotation(int32_t rotationDegrees) {
154ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        uint32_t transform;
155ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        switch (rotationDegrees) {
156ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 0: transform = 0; break;
157ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 90: transform = HAL_TRANSFORM_ROT_90; break;
158ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 180: transform = HAL_TRANSFORM_ROT_180; break;
159ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 270: transform = HAL_TRANSFORM_ROT_270; break;
160ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            default: transform = 0; break;
161ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        }
162ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
163ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        if (transform) {
164ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            CHECK_EQ(0, native_window_set_buffers_transform(
165ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                        mNativeWindow.get(), transform));
166ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        }
167ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
168ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1696a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);
1706a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    AwesomeNativeWindowRenderer &operator=(
1716a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis            const AwesomeNativeWindowRenderer &);
1726a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis};
1736a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1747cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang// To collect the decoder usage
1757cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wangvoid addBatteryData(uint32_t params) {
1767cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    sp<IBinder> binder =
1777cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        defaultServiceManager()->getService(String16("media.player"));
1787cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
1797cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    CHECK(service.get() != NULL);
1807cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
1817cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    service->addBatteryData(params);
1827cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang}
183e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
1847cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang////////////////////////////////////////////////////////////////////////////////
185bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas HuberAwesomePlayer::AwesomePlayer()
1862e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    : mQueueStarted(false),
1879b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mUIDValid(false),
1882e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber      mTimeSource(NULL),
189fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber      mVideoRendererIsPreview(false),
190bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber      mAudioPlayer(NULL),
191b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong      mDisplayWidth(0),
192b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong      mDisplayHeight(0),
193bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber      mFlags(0),
194acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber      mExtractorFlags(0),
1957b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber      mVideoBuffer(NULL),
196150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber      mDecryptHandle(NULL),
1977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mLastVideoTimeUs(-1),
1987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mTextPlayer(NULL) {
199e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(mClient.connect(), (status_t)OK);
200bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
201bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    DataSource::RegisterDefaultSniffers();
202bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
203c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
204bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = false;
205c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
206bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = false;
207c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
20866b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mBufferingEventPending = false;
209145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate);
210145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoEventPending = false;
211c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
212c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mCheckAudioStatusEvent = new AwesomeEvent(
213c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            this, &AwesomePlayer::onCheckAudioStatus);
214c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2151862a33b246249630b654182afb5914da3480d4cAndreas Huber    mAudioStatusEventPending = false;
216bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
217bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset();
218bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
219bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
220bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas HuberAwesomePlayer::~AwesomePlayer() {
2212e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    if (mQueueStarted) {
2222e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        mQueue.stop();
2232e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    }
224bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
225bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset();
226bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
227bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mClient.disconnect();
228bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
229bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
23066b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Hubervoid AwesomePlayer::cancelPlayerEvents(bool keepBufferingGoing) {
231bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.cancelEvent(mVideoEvent->eventID());
232bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = false;
233bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.cancelEvent(mStreamDoneEvent->eventID());
234bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = false;
2351862a33b246249630b654182afb5914da3480d4cAndreas Huber    mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
2361862a33b246249630b654182afb5914da3480d4cAndreas Huber    mAudioStatusEventPending = false;
237145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mQueue.cancelEvent(mVideoLagEvent->eventID());
238145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEventPending = false;
23966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
24066b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    if (!keepBufferingGoing) {
24166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        mQueue.cancelEvent(mBufferingEvent->eventID());
24266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        mBufferingEventPending = false;
24366b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
244bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
245bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
2460726045216f576e97672ebeefc265d39c4ebaaa5Andreas Hubervoid AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
247bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
248bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mListener = listener;
249bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
250bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
2519b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid AwesomePlayer::setUID(uid_t uid) {
252c32589a79f8120ac0060945fffc50279143989aaAndreas Huber    LOGV("AwesomePlayer running on behalf of uid %d", uid);
2539b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2549b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
2559b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
2569b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
2579b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2585561ccf4a8db88a2e44eac1b3ed13b4ff53a7f20Andreas Huberstatus_t AwesomePlayer::setDataSource(
2595561ccf4a8db88a2e44eac1b3ed13b4ff53a7f20Andreas Huber        const char *uri, const KeyedVector<String8, String8> *headers) {
260bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
2617b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    return setDataSource_l(uri, headers);
2627b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber}
263bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
2647b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huberstatus_t AwesomePlayer::setDataSource_l(
2657b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        const char *uri, const KeyedVector<String8, String8> *headers) {
266bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset_l();
267bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
268bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mUri = uri;
26966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
270bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (headers) {
271bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        mUriHeaders = *headers;
2727314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
2737314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
2747314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        if (index >= 0) {
2757314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber            // Browser is in "incognito" mode, suppress logging URLs.
2767314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
2777314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber            // This isn't something that should be passed to the server.
2787314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber            mUriHeaders.removeItemsAt(index);
2797314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
280a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(INCOGNITO, SET);
2817314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        }
2827314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber    }
2837314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
2847314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber    if (!(mFlags & INCOGNITO)) {
2857314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        LOGI("setDataSource_l('%s')", mUri.string());
2867314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber    } else {
2877314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        LOGI("setDataSource_l(URL suppressed)");
28866b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
28966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
290bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    // The actual work will be done during preparation in the call to
291bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    // ::finishSetDataSource_l to avoid blocking the calling thread in
292bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    // setDataSource for any significant time.
29366b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
294a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
295a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
296a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFd = -1;
297a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mURI = mUri;
298a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
299a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
300bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    return OK;
301bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
302bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
303bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::setDataSource(
304bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        int fd, int64_t offset, int64_t length) {
305bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
306bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
307bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset_l();
308bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
3097b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    sp<DataSource> dataSource = new FileSource(fd, offset, length);
310bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
3117b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    status_t err = dataSource->initCheck();
312bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
313bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (err != OK) {
314bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return err;
315bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
316bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
3177b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mFileSource = dataSource;
3187b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
319a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
320a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
321a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFd = fd;
322a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mURI = String8();
323a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
324a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
3257b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    return setDataSource_l(dataSource);
3267b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber}
3277b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
328e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstatus_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
32985704836f33a199d7e442a23db82abbd5620d35dAndreas Huber    return INVALID_OPERATION;
330e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
331e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
3327b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huberstatus_t AwesomePlayer::setDataSource_l(
3337b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        const sp<DataSource> &dataSource) {
3347b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
335bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
336bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (extractor == NULL) {
337bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return UNKNOWN_ERROR;
338bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
339bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
340b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
3418f64134f749e4f7861a08a3063450fc714c4651dGloria Wang    if (mDecryptHandle != NULL) {
3428f64134f749e4f7861a08a3063450fc714c4651dGloria Wang        CHECK(mDrmManagerClient);
3438f64134f749e4f7861a08a3063450fc714c4651dGloria Wang        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
3447340743ce30766af6334bbd9acf813eb66dd5a60Gloria Wang            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
3458f64134f749e4f7861a08a3063450fc714c4651dGloria Wang        }
346dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
347dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
348bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return setDataSource_l(extractor);
349bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
350bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
351bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
3527fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    // Attempt to approximate overall stream bitrate by summing all
3537fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    // tracks' individual bitrates, if not all of them advertise bitrate,
3547fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    // we have to fail.
3557fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3567fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    int64_t totalBitRate = 0;
3577fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3587fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
3597fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
3607fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3617fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        int32_t bitrate;
3627fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
363a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            const char *mime;
364a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            CHECK(meta->findCString(kKeyMIMEType, &mime));
365c32589a79f8120ac0060945fffc50279143989aaAndreas Huber            LOGV("track of type '%s' does not publish bitrate", mime);
366a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
3677fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            totalBitRate = -1;
3687fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            break;
3697fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        }
3707fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3717fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        totalBitRate += bitrate;
3727fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    }
3737fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3747fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    mBitrate = totalBitRate;
3757fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3767fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    LOGV("mBitrate = %lld bits/sec", mBitrate);
3777fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
378a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
379a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
380a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mBitrate = mBitrate;
381a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mTracks.clear();
382a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mAudioTrackIndex = -1;
383a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoTrackIndex = -1;
384a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
385a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
386bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    bool haveAudio = false;
387bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    bool haveVideo = false;
388bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
389bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
390bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
391bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        const char *mime;
392bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
393bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
394bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
39588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber            setVideoSource(extractor->getTrack(i));
39688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber            haveVideo = true;
397b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong
398b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            // Set the presentation/display size
399b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            int32_t displayWidth, displayHeight;
400b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
401b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            if (success) {
402b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong                success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
403b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            }
404b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            if (success) {
405b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong                mDisplayWidth = displayWidth;
406b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong                mDisplayHeight = displayHeight;
407b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong            }
408b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong
409a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            {
410a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                Mutex::Autolock autoLock(mStatsLock);
411a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                mStats.mVideoTrackIndex = mStats.mTracks.size();
412a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                mStats.mTracks.push();
413a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                TrackStat *stat =
414a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
415a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                stat->mMIME = mime;
416a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            }
417bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
41888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber            setAudioSource(extractor->getTrack(i));
41988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber            haveAudio = true;
4208ae49d87b98d57d6758b0c51b95e28a6581a79f1Andreas Huber
421a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            {
422a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                Mutex::Autolock autoLock(mStatsLock);
423a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                mStats.mAudioTrackIndex = mStats.mTracks.size();
424a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                mStats.mTracks.push();
425a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                TrackStat *stat =
426a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
427a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                stat->mMIME = mime;
428a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            }
429a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
4306954535ba64374e4e941cd83019a7af53edfb098Andreas Huber            if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
4316954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                // Only do this for vorbis audio, none of the other audio
4326954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                // formats even support this ringtone specific hack and
4336954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                // retrieving the metadata on some extractors may turn out
4346954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                // to be very expensive.
4356954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                sp<MetaData> fileMeta = extractor->getMetaData();
4366954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                int32_t loop;
4376954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                if (fileMeta != NULL
4386954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                        && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
439a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    modifyFlags(AUTO_LOOPING, SET);
4406954535ba64374e4e941cd83019a7af53edfb098Andreas Huber                }
4418ae49d87b98d57d6758b0c51b95e28a6581a79f1Andreas Huber            }
4427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
4437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            addTextSource(extractor->getTrack(i));
444bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
445bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
446bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
447acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    if (!haveAudio && !haveVideo) {
448acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber        return UNKNOWN_ERROR;
449acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    }
450acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
451acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    mExtractorFlags = extractor->flags();
452acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
453acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    return OK;
454bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
455bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
456bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::reset() {
457bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
458bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset_l();
459bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
460bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
461bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::reset_l() {
462b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mDisplayWidth = 0;
463b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    mDisplayHeight = 0;
46465a170e3ac593a29abd0c76e9aa531fabad7f56dAndreas Huber
465dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDecryptHandle != NULL) {
466dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
467dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    Playback::STOP, 0);
468dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDecryptHandle = NULL;
469dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDrmManagerClient = NULL;
470dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
471dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
4727cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (mFlags & PLAYING) {
4737cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
4747cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
4757cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            params |= IMediaPlayerService::kBatteryDataTrackAudio;
4767cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
4777cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (mVideoSource != NULL) {
4787cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            params |= IMediaPlayerService::kBatteryDataTrackVideo;
4797cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
4807cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        addBatteryData(params);
4817cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
4827cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
483e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    if (mFlags & PREPARING) {
484a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(PREPARE_CANCELLED, SET);
485e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        if (mConnectingDataSource != NULL) {
486e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            LOGI("interrupting the connection process");
487e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            mConnectingDataSource->disconnect();
488f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber        } else if (mConnectingRTSPController != NULL) {
489f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber            LOGI("interrupting the connection process");
490f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber            mConnectingRTSPController->disconnect();
491e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        }
4926a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber
4936a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber        if (mFlags & PREPARING_CONNECTED) {
4946a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber            // We are basically done preparing, we're just buffering
4956a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber            // enough data to start playback, we can safely interrupt that.
4966a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber            finishAsyncPrepare_l();
4976a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber        }
498e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    }
499e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
500bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    while (mFlags & PREPARING) {
501bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        mPreparedCondition.wait(mLock);
502bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
503bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
504bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    cancelPlayerEvents();
505bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
506681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    mWVMExtractor.clear();
5070a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    mCachedSource.clear();
50888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mAudioTrack.clear();
50988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mVideoTrack.clear();
51088d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
5117b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // Shutdown audio first, so that the respone to the reset request
5127b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // appears to happen instantaneously as far as the user is concerned
5137b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // If we did this later, audio would continue playing while we
5147b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // shutdown the video-related resources and the player appear to
5157b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // not be as responsive to a reset request.
5165b75fdc8fbc026453888cbb2d3fe31345394618bGloria Wang    if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
5175b75fdc8fbc026453888cbb2d3fe31345394618bGloria Wang            && mAudioSource != NULL) {
518e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        // If we had an audio player, it would have effectively
519e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        // taken possession of the audio source and stopped it when
520e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        // _it_ is stopped. Otherwise this is still our responsibility.
521e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mAudioSource->stop();
522e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    }
5237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mAudioSource.clear();
5247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5257b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mTimeSource = NULL;
5267b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5277b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    delete mAudioPlayer;
5287b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mAudioPlayer = NULL;
5297b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextPlayer != NULL) {
5317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        delete mTextPlayer;
5327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer = NULL;
5337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
5347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
535b9280d5c2313c41eb490f58198c4e59118e0e3e6Andreas Huber    mVideoRenderer.clear();
536b9280d5c2313c41eb490f58198c4e59118e0e3e6Andreas Huber
537cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber    if (mRTSPController != NULL) {
538cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber        mRTSPController->disconnect();
539cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber        mRTSPController.clear();
540cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber    }
541cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber
542bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoSource != NULL) {
543150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        shutdownVideoDecoder_l();
544bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
545bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
546bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mDurationUs = -1;
547a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(0, ASSIGN);
548acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    mExtractorFlags = 0;
549bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mTimeSourceDeltaUs = 0;
550bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoTimeUs = 0;
551bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
55264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    mSeeking = NO_SEEK;
553af64a8a6ad89f52685e822dca30742a4132c9ae6Gloria Wang    mSeekNotificationSent = true;
554bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mSeekTimeUs = 0;
55566b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
556bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mUri.setTo("");
557bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mUriHeaders.clear();
5587b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5597b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mFileSource.clear();
5607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5617fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    mBitrate = -1;
562150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mLastVideoTimeUs = -1;
563a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
564a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
565a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
566a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFd = -1;
567a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mURI = String8();
568a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mBitrate = -1;
569a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mAudioTrackIndex = -1;
570a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoTrackIndex = -1;
571a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mNumVideoFramesDecoded = 0;
572a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mNumVideoFramesDropped = 0;
573a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoWidth = -1;
574a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoHeight = -1;
575a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFlags = 0;
576a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mTracks.clear();
577a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
578a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
57999590d29c9d3081cadfccd036842f5ce9a7debefAndreas Huber    mWatchForAudioSeekComplete = false;
58099590d29c9d3081cadfccd036842f5ce9a7debefAndreas Huber    mWatchForAudioEOS = false;
581bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
582bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
583c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Hubervoid AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
5840726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber    if (mListener != NULL) {
5850726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber        sp<MediaPlayerBase> listener = mListener.promote();
5860726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber
5870726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber        if (listener != NULL) {
588c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            listener->sendEvent(msg, ext1, ext2);
58966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        }
59066b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
59166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber}
59266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
5937fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huberbool AwesomePlayer::getBitrate(int64_t *bitrate) {
594c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t size;
5957fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    if (mDurationUs >= 0 && mCachedSource != NULL
5967fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            && mCachedSource->getSize(&size) == OK) {
5977fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
5987fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        return true;
5997fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    }
6007fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
6017fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    if (mBitrate >= 0) {
6027fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        *bitrate = mBitrate;
6037fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        return true;
6047fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    }
6057fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
6067fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    *bitrate = 0;
6077fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
6087fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    return false;
6097fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber}
6107fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
6118650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber// Returns true iff cached duration is available/applicable.
6128650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huberbool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
6137fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    int64_t bitrate;
6148650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
6158650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mRTSPController != NULL) {
6168650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        *durationUs = mRTSPController->getQueueDurationUs(eos);
6178650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        return true;
6187fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    } else if (mCachedSource != NULL && getBitrate(&bitrate)) {
6191bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        status_t finalStatus;
6201bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
6218650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
6221bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        *eos = (finalStatus != OK);
6238650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        return true;
624681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    } else if (mWVMExtractor != NULL) {
625681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        status_t finalStatus;
626681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        *durationUs = mWVMExtractor->getCachedDurationUs(&finalStatus);
627681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        *eos = (finalStatus != OK);
628681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        return true;
6298650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
6308650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
6318650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    return false;
6328650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber}
6338650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
63434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid AwesomePlayer::ensureCacheIsFetching_l() {
63534ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber    if (mCachedSource != NULL) {
63634ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber        mCachedSource->resumeFetchingIfNecessary();
63734ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber    }
63834ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber}
63934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber
640145e68fc778275963189b02a1adcbe27cce4d769Andreas Hubervoid AwesomePlayer::onVideoLagUpdate() {
641145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    Mutex::Autolock autoLock(mLock);
642145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    if (!mVideoLagEventPending) {
643145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        return;
644145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    }
645145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEventPending = false;
646145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
647145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
648145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
649145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
6505dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
651145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        LOGV("video late by %lld ms.", videoLateByUs / 1000ll);
652145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
653145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        notifyListener_l(
654145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber                MEDIA_INFO,
655145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber                MEDIA_INFO_VIDEO_TRACK_LAGGING,
656145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber                videoLateByUs / 1000ll);
657145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    }
658145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
659145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    postVideoLagEvent_l();
660145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber}
661145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
66266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Hubervoid AwesomePlayer::onBufferingUpdate() {
66366b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    Mutex::Autolock autoLock(mLock);
664d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    if (!mBufferingEventPending) {
665d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber        return;
666d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    }
66766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mBufferingEventPending = false;
66866b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
6698650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mCachedSource != NULL) {
6701bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        status_t finalStatus;
6711bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
6721bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        bool eos = (finalStatus != OK);
673c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
6748650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (eos) {
6751bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney            if (finalStatus == ERROR_END_OF_STREAM) {
6761bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
6771bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney            }
67883977eb230d829cfe520f55d7977037a904ce548Andreas Huber            if (mFlags & PREPARING) {
67983977eb230d829cfe520f55d7977037a904ce548Andreas Huber                LOGV("cache has reached EOS, prepare is done.");
68083977eb230d829cfe520f55d7977037a904ce548Andreas Huber                finishAsyncPrepare_l();
68183977eb230d829cfe520f55d7977037a904ce548Andreas Huber            }
6828650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        } else {
6837fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            int64_t bitrate;
6847fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            if (getBitrate(&bitrate)) {
6858650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                size_t cachedSize = mCachedSource->cachedSize();
6868650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
687c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
6888650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
6898650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                if (percentage > 100) {
6908650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    percentage = 100;
6918650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                }
692c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
6938650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
6948650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            } else {
6958650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                // We don't know the bitrate of the stream, use absolute size
6968650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                // limits to maintain the cache.
6978650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
6988650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                if ((mFlags & PLAYING) && !eos
6998650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
7008650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    LOGI("cache is running low (< %d) , pausing.",
7018650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                         kLowWaterMarkBytes);
702a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    modifyFlags(CACHE_UNDERRUN, SET);
7038650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    pause_l();
70434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber                    ensureCacheIsFetching_l();
7055b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                    sendCacheStats();
7068650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
7078650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
7088650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    if (mFlags & CACHE_UNDERRUN) {
7098650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        LOGI("cache has filled up (> %d), resuming.",
7108650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                             kHighWaterMarkBytes);
711a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                        modifyFlags(CACHE_UNDERRUN, CLEAR);
7128650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        play_l();
7138650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
7148650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    } else if (mFlags & PREPARING) {
7158650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        LOGV("cache has filled up (> %d), prepare is done",
7168650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                             kHighWaterMarkBytes);
7178650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        finishAsyncPrepare_l();
7188650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    }
7198650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                }
7208650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            }
7218650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        }
722681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    } else if (mWVMExtractor != NULL) {
723681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        status_t finalStatus;
724681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
725681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        int64_t cachedDurationUs
726681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            = mWVMExtractor->getCachedDurationUs(&finalStatus);
727681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
728681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        bool eos = (finalStatus != OK);
729681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
730681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (eos) {
731681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            if (finalStatus == ERROR_END_OF_STREAM) {
732681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
733681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            }
734681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            if (mFlags & PREPARING) {
735681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                LOGV("cache has reached EOS, prepare is done.");
736681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                finishAsyncPrepare_l();
737681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            }
738681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        } else {
739681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
740681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            if (percentage > 100) {
741681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                percentage = 100;
742681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            }
743681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
744681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
745681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
7462415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    }
7472415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber
7488650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    int64_t cachedDurationUs;
7492a4b49bd3863024884a694b454e2e452752e6ea0Andreas Huber    bool eos;
7508650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
75134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber        LOGV("cachedDurationUs = %.2f secs, eos=%d",
75234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber             cachedDurationUs / 1E6, eos);
75334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber
754100a4408968b90e314526185d572c72ea4cc784aAndreas Huber        int64_t highWaterMarkUs =
755100a4408968b90e314526185d572c72ea4cc784aAndreas Huber            (mRTSPController != NULL) ? kHighWaterMarkRTSPUs : kHighWaterMarkUs;
756100a4408968b90e314526185d572c72ea4cc784aAndreas Huber
7578650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if ((mFlags & PLAYING) && !eos
7588650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                && (cachedDurationUs < kLowWaterMarkUs)) {
7598650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            LOGI("cache is running low (%.2f secs) , pausing.",
7608650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                 cachedDurationUs / 1E6);
761a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(CACHE_UNDERRUN, SET);
7628650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            pause_l();
76334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber            ensureCacheIsFetching_l();
7645b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            sendCacheStats();
7658650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
766100a4408968b90e314526185d572c72ea4cc784aAndreas Huber        } else if (eos || cachedDurationUs > highWaterMarkUs) {
7678650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            if (mFlags & CACHE_UNDERRUN) {
7688650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                LOGI("cache has filled up (%.2f secs), resuming.",
7698650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                     cachedDurationUs / 1E6);
770a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(CACHE_UNDERRUN, CLEAR);
7718650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                play_l();
7728650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
7738650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            } else if (mFlags & PREPARING) {
7748650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                LOGV("cache has filled up (%.2f secs), prepare is done",
7758650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                     cachedDurationUs / 1E6);
7768650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                finishAsyncPrepare_l();
7772a4b49bd3863024884a694b454e2e452752e6ea0Andreas Huber            }
7782a4b49bd3863024884a694b454e2e452752e6ea0Andreas Huber        }
7790a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    }
7800a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
7810a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    postBufferingEvent_l();
7820726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber}
7830726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber
7845b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongvoid AwesomePlayer::sendCacheStats() {
7855b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    sp<MediaPlayerBase> listener = mListener.promote();
786b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong    if (listener != NULL && mCachedSource != NULL) {
7875b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        int32_t kbps = 0;
7885b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        status_t err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
7895b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        if (err == OK) {
7905b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            listener->sendEvent(
7915b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
7925b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        }
7935b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
7945b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
7955b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
796bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::onStreamDone() {
797bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    // Posted whenever any stream finishes playing.
798bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
799bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
800d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    if (!mStreamDoneEventPending) {
801d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber        return;
802d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    }
803bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = false;
804bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
805ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber    if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
8065d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
8075d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
8085d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        notifyListener_l(
8095d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
8105d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
811b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        pause_l(true /* at eos */);
8125d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
813a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AT_EOS, SET);
8145d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        return;
8155d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    }
8165d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
8175d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    const bool allDone =
8185d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
8195d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber            && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
8205d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
8215d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    if (!allDone) {
8225d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        return;
8235d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    }
8245d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
825cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber    if ((mFlags & LOOPING)
826cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber            || ((mFlags & AUTO_LOOPING)
827cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber                && (mAudioSink == NULL || mAudioSink->realtime()))) {
828cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber        // Don't AUTO_LOOP if we're being recorded, since that cannot be
829cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber        // turned off and recording would go on indefinitely.
830cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber
831bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        seekTo_l(0);
832bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
833a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        if (mVideoSource != NULL) {
834bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            postVideoEvent_l();
835bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
836bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    } else {
8375d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        LOGV("MEDIA_PLAYBACK_COMPLETE");
8385d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
839bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
840b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        pause_l(true /* at eos */);
8412e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
842a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AT_EOS, SET);
843bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
844bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
845bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
846bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::play() {
847bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
8480a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
849a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(CACHE_UNDERRUN, CLEAR);
8500a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
8517b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    return play_l();
8527b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber}
853bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
8547b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huberstatus_t AwesomePlayer::play_l() {
855a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(SEEK_PREVIEW, CLEAR);
8562b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
857bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mFlags & PLAYING) {
858bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return OK;
859bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
860bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
861bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (!(mFlags & PREPARED)) {
862bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        status_t err = prepare_l();
863bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
864bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        if (err != OK) {
865bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber            return err;
866bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        }
867bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
868bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
869a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PLAYING, SET);
870a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(FIRST_FRAME, SET);
871bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
872c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang    if (mDecryptHandle != NULL) {
873c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang        int64_t position;
874c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang        getPosition(&position);
875c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
876c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang                Playback::START, position / 1000);
877c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang    }
878c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang
879bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mAudioSource != NULL) {
880bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        if (mAudioPlayer == NULL) {
881bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (mAudioSink != NULL) {
882ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                mAudioPlayer = new AudioPlayer(mAudioSink, this);
883bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                mAudioPlayer->setSource(mAudioSource);
884e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber
885f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                mTimeSource = mAudioPlayer;
88688c030e0e0152791ff74f90249f55fce01371198Andreas Huber
887b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // If there was a seek request before we ever started,
888b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // honor the request now.
889b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // Make sure to do this before starting the audio player
890b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // to avoid a race condition.
891b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                seekAudioIfNecessary_l();
892f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            }
893f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        }
89488c030e0e0152791ff74f90249f55fce01371198Andreas Huber
895f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        CHECK(!(mFlags & AUDIO_RUNNING));
896c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang
897f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        if (mVideoSource == NULL) {
8985442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            // We don't want to post an error notification at this point,
8995442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            // the error returned from MediaPlayer::start() will suffice.
9005442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber
9015442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            status_t err = startAudioPlayer_l(
9025442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber                    false /* sendErrorNotification */);
903bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
904f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            if (err != OK) {
905f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                delete mAudioPlayer;
906f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                mAudioPlayer = NULL;
907bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
908a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags((PLAYING | FIRST_FRAME), CLEAR);
9091862a33b246249630b654182afb5914da3480d4cAndreas Huber
910f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                if (mDecryptHandle != NULL) {
911f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                    mDrmManagerClient->setPlaybackStatus(
912f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                            mDecryptHandle, Playback::STOP, 0);
913f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                }
914f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
915f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                return err;
916bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
917bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
918bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
919bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
920bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mTimeSource == NULL && mAudioPlayer == NULL) {
9215d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        mTimeSource = &mSystemTimeSource;
922bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
923bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
924bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoSource != NULL) {
925a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        // Kick off video playback
926a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        postVideoEvent_l();
927145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
928145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        if (mAudioSource != NULL && mVideoSource != NULL) {
929145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber            postVideoLagEvent_l();
930145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        }
931bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
932bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
9332e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    if (mFlags & AT_EOS) {
9342e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        // Legacy behaviour, if a stream finishes playing and then
9352e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        // is started again, we play from the start...
9362e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        seekTo_l(0);
9372e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    }
9382e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
9397cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
9407cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        | IMediaPlayerService::kBatteryDataTrackDecoder;
9417cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
9427cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackAudio;
9437cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
9447cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (mVideoSource != NULL) {
9457cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackVideo;
9467cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
9477cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    addBatteryData(params);
9487cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
949bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
950bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
951bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
9525442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huberstatus_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
953f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    CHECK(!(mFlags & AUDIO_RUNNING));
954f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
955f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (mAudioSource == NULL || mAudioPlayer == NULL) {
956f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        return OK;
957f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    }
958f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
959f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (!(mFlags & AUDIOPLAYER_STARTED)) {
960a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AUDIOPLAYER_STARTED, SET);
961f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
962c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        bool wasSeeking = mAudioPlayer->isSeeking();
963c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
964f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        // We've already started the MediaSource in order to enable
965f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        // the prefetcher to read its data.
966f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        status_t err = mAudioPlayer->start(
967f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                true /* sourceAlreadyStarted */);
968f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
969f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        if (err != OK) {
9705442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            if (sendErrorNotification) {
9715442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber                notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
9725442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            }
9735442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber
974f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            return err;
975f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        }
976c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
977c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        if (wasSeeking) {
978c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber            CHECK(!mAudioPlayer->isSeeking());
979c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
980c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber            // We will have finished the seek while starting the audio player.
98102f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            postAudioSeekComplete();
982c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        }
983f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    } else {
984f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        mAudioPlayer->resume();
985f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    }
986f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
987a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(AUDIO_RUNNING, SET);
988f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
989f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    mWatchForAudioEOS = true;
990f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
991f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    return OK;
992f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber}
993f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
9945daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Hubervoid AwesomePlayer::notifyVideoSize_l() {
9955daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    sp<MetaData> meta = mVideoSource->getFormat();
9965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
997f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t cropLeft, cropTop, cropRight, cropBottom;
998f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findRect(
999f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
1000f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        int32_t width, height;
1001f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        CHECK(meta->findInt32(kKeyWidth, &width));
1002f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        CHECK(meta->findInt32(kKeyHeight, &height));
1003f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
1004f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        cropLeft = cropTop = 0;
1005f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        cropRight = width - 1;
1006f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        cropBottom = height - 1;
1007f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
1008f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        LOGV("got dimensions only %d x %d", width, height);
1009f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    } else {
1010f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        LOGV("got crop rect %d, %d, %d, %d",
1011f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber             cropLeft, cropTop, cropRight, cropBottom);
1012f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
1013f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
10149cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    int32_t displayWidth;
10159cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
10169cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong        LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
10179cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong        mDisplayWidth = displayWidth;
10189cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    }
10199cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    int32_t displayHeight;
10209cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
10219cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong        LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
10229cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong        mDisplayHeight = displayHeight;
10239cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    }
10249cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong
1025f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t usableWidth = cropRight - cropLeft + 1;
1026f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t usableHeight = cropBottom - cropTop + 1;
1027b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    if (mDisplayWidth != 0) {
1028b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong        usableWidth = mDisplayWidth;
1029b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    }
1030b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    if (mDisplayHeight != 0) {
1031b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong        usableHeight = mDisplayHeight;
1032b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    }
10335daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1034a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
1035a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
1036a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoWidth = usableWidth;
1037a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoHeight = usableHeight;
1038a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
1039a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1040ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t rotationDegrees;
1041ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (!mVideoTrack->getFormat()->findInt32(
1042ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                kKeyRotation, &rotationDegrees)) {
1043ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
1044ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1045ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1046ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (rotationDegrees == 90 || rotationDegrees == 270) {
1047ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        notifyListener_l(
1048f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
1049ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
1050ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        notifyListener_l(
1051f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
1052ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
10535daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
10545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1055bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::initRenderer_l() {
10561173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (mNativeWindow == NULL) {
10570a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        return;
10580a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    }
1059bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
10600a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    sp<MetaData> meta = mVideoSource->getFormat();
1061bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
10620a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    int32_t format;
10630a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    const char *component;
10640a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    int32_t decodedWidth, decodedHeight;
10650a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &format));
10660a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findCString(kKeyDecoderComponent, &component));
10670a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
10680a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
10694844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber
1070ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t rotationDegrees;
1071ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (!mVideoTrack->getFormat()->findInt32(
1072ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                kKeyRotation, &rotationDegrees)) {
1073ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
1074ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1075ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
10760a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    mVideoRenderer.clear();
10774844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber
10780a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    // Must ensure that mVideoRenderer's destructor is actually executed
10790a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    // before creating a new one.
10800a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    IPCThreadState::self()->flushCommands();
10810a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber
1082bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (USE_SURFACE_ALLOC
1083bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            && !strncmp(component, "OMX.", 4)
1084bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            && strncmp(component, "OMX.google.", 11)) {
10850a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // Hardware decoders avoid the CPU color conversion by decoding
10860a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // directly to ANativeBuffers, so we must use a renderer that
10870a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // just pushes those buffers to the ANativeWindow.
1088ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mVideoRenderer =
10891173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
10900a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    } else {
10910a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // Other decoders are instantiated locally and as a consequence
10920a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // allocate their buffers in local address space.  This renderer
10930a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // then performs a color conversion and copy to get the data
10940a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // into the ANativeBuffer.
10951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
1096bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1097bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1098bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1099bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::pause() {
1100bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
11010a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1102a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(CACHE_UNDERRUN, CLEAR);
11030a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1104bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return pause_l();
1105bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1106bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1107b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huberstatus_t AwesomePlayer::pause_l(bool at_eos) {
1108bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (!(mFlags & PLAYING)) {
1109bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return OK;
1110bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1111bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
111266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    cancelPlayerEvents(true /* keepBufferingGoing */);
1113bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1114f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1115b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        if (at_eos) {
1116b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            // If we played the audio stream to completion we
1117b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            // want to make sure that all samples remaining in the audio
1118b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            // track's queue are played out.
1119b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioPlayer->pause(true /* playPendingSamples */);
1120b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        } else {
1121b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioPlayer->pause();
1122b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        }
1123f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
1124a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AUDIO_RUNNING, CLEAR);
1125bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1126bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
11277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mFlags & TEXTPLAYER_STARTED) {
11287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer->pause();
1129a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(TEXT_RUNNING, CLEAR);
11307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
11317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1132a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PLAYING, CLEAR);
1133bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1134dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDecryptHandle != NULL) {
1135dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1136dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                Playback::PAUSE, 0);
1137dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
1138dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
11397cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
11407cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
11417cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackAudio;
11427cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
11437cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (mVideoSource != NULL) {
11447cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackVideo;
11457cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
11467cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
11477cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    addBatteryData(params);
11487cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
1149bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1150bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1151bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1152bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberbool AwesomePlayer::isPlaying() const {
11530a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
1154bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1155bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
115663970b42f101c87db7cfd26d43b0d300260b1582Andreas Huberstatus_t AwesomePlayer::setSurface(const sp<Surface> &surface) {
11575daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    Mutex::Autolock autoLock(mLock);
11585daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
11595daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    mSurface = surface;
116063970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    return setNativeWindow_l(surface);
11611173118eace0e9e347cb007f0da817cee87579edGlenn Kasten}
11621173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
116363970b42f101c87db7cfd26d43b0d300260b1582Andreas Huberstatus_t AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
11641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    Mutex::Autolock autoLock(mLock);
11651173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
11661173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    mSurface.clear();
116763970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
116863970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    status_t err;
11691173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (surfaceTexture != NULL) {
117063970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        err = setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
117180ec929862bcfe8582984f3a28e7a4ca5f4f27bbGloria Wang    } else {
117263970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        err = setNativeWindow_l(NULL);
11731173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    }
117463970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
117563970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    return err;
1176150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber}
11771173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
1178150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Hubervoid AwesomePlayer::shutdownVideoDecoder_l() {
1179150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (mVideoBuffer) {
1180150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mVideoBuffer->release();
1181150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mVideoBuffer = NULL;
1182150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1183150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1184150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mVideoSource->stop();
1185150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1186150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    // The following hack is necessary to ensure that the OMX
1187150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    // component is completely released by the time we may try
1188150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    // to instantiate it again.
1189150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    wp<MediaSource> tmp = mVideoSource;
1190150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mVideoSource.clear();
1191150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    while (tmp.promote() != NULL) {
1192150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        usleep(1000);
1193150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1194150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    IPCThreadState::self()->flushCommands();
1195c32589a79f8120ac0060945fffc50279143989aaAndreas Huber    LOGV("video decoder shutdown completed");
1196150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber}
1197150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
119863970b42f101c87db7cfd26d43b0d300260b1582Andreas Huberstatus_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
1199150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mNativeWindow = native;
1200150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1201150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (mVideoSource == NULL) {
120263970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        return OK;
1203150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1204150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1205c32589a79f8120ac0060945fffc50279143989aaAndreas Huber    LOGV("attempting to reconfigure to use new surface");
1206150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1207150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    bool wasPlaying = (mFlags & PLAYING) != 0;
1208150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1209150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    pause_l();
1210150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mVideoRenderer.clear();
1211150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1212150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    shutdownVideoDecoder_l();
1213150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
121463970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    status_t err = initVideoDecoder();
121563970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
121663970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    if (err != OK) {
121763970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        LOGE("failed to reinstantiate video decoder after surface change.");
121863970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        return err;
121963970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    }
1220150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1221150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (mLastVideoTimeUs >= 0) {
1222150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mSeeking = SEEK;
1223150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mSeekTimeUs = mLastVideoTimeUs;
1224a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
1225150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1226150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1227150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (wasPlaying) {
1228150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        play_l();
1229150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
123063970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
123163970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    return OK;
12325daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
12335daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1234bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::setAudioSink(
1235bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        const sp<MediaPlayerBase::AudioSink> &audioSink) {
1236bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
1237bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1238bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mAudioSink = audioSink;
1239bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1240bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1241bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::setLooping(bool shouldLoop) {
1242bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
1243bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1244a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(LOOPING, CLEAR);
1245bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1246bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (shouldLoop) {
1247a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(LOOPING, SET);
1248bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1249bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1250bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1251bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1252bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1253bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::getDuration(int64_t *durationUs) {
12542415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    Mutex::Autolock autoLock(mMiscStateLock);
1255bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1256bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mDurationUs < 0) {
1257bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return UNKNOWN_ERROR;
1258bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1259bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1260bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    *durationUs = mDurationUs;
1261bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1262bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1263bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1264bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1265bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::getPosition(int64_t *positionUs) {
12668d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    if (mRTSPController != NULL) {
12678d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        *positionUs = mRTSPController->getNormalPlayTimeUs();
12688d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    }
126964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    else if (mSeeking != NO_SEEK) {
1270dac4ee72bac87388a1495e098f39d73168c8078fAndreas Huber        *positionUs = mSeekTimeUs;
12715dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    } else if (mVideoSource != NULL
12725dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber            && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
12732415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber        Mutex::Autolock autoLock(mMiscStateLock);
1274bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        *positionUs = mVideoTimeUs;
1275bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    } else if (mAudioPlayer != NULL) {
1276bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        *positionUs = mAudioPlayer->getMediaTimeUs();
1277bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    } else {
1278bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        *positionUs = 0;
1279bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1280bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1281bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1282bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1283bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1284bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::seekTo(int64_t timeUs) {
128570f521de2675ce6eedf4b22beed94ea1289b0f38Andreas Huber    if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
1286acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber        Mutex::Autolock autoLock(mLock);
1287acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber        return seekTo_l(timeUs);
1288acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    }
1289acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
1290acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    return OK;
1291bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1292bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
12937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
12947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextPlayer != NULL) {
12957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        if (index >= 0) { // to turn on a text track
12967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            status_t err = mTextPlayer->setTimedTextTrackIndex(index);
12977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (err != OK) {
12987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return err;
12997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1301a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(TEXT_RUNNING, SET);
1302a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(TEXTPLAYER_STARTED, SET);
13037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            return OK;
13047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        } else { // to turn off the text track display
13057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mFlags  & TEXT_RUNNING) {
1306a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(TEXT_RUNNING, CLEAR);
13077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mFlags  & TEXTPLAYER_STARTED) {
1309a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(TEXTPLAYER_STARTED, CLEAR);
13107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
13117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            return mTextPlayer->setTimedTextTrackIndex(index);
13137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
13147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    } else {
13157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return INVALID_OPERATION;
13167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
13177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
13187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13190dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber// static
13200dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Hubervoid AwesomePlayer::OnRTSPSeekDoneWrapper(void *cookie) {
13210dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber    static_cast<AwesomePlayer *>(cookie)->onRTSPSeekDone();
13220dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber}
13230dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber
13240dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Hubervoid AwesomePlayer::onRTSPSeekDone() {
1325af64a8a6ad89f52685e822dca30742a4132c9ae6Gloria Wang    if (!mSeekNotificationSent) {
1326af64a8a6ad89f52685e822dca30742a4132c9ae6Gloria Wang        notifyListener_l(MEDIA_SEEK_COMPLETE);
1327af64a8a6ad89f52685e822dca30742a4132c9ae6Gloria Wang        mSeekNotificationSent = true;
1328af64a8a6ad89f52685e822dca30742a4132c9ae6Gloria Wang    }
13290dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber}
13300dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber
1331bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::seekTo_l(int64_t timeUs) {
1332cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber    if (mRTSPController != NULL) {
13331a49a13f20a06c2b58b97ad311a90d8eb0956052Gloria Wang        mSeekNotificationSent = false;
13340dcd837af4169bdb6fb2a0c384722dc4f57433c6Andreas Huber        mRTSPController->seekAsync(timeUs, OnRTSPSeekDoneWrapper, this);
1335cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber        return OK;
1336cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber    }
1337cce326fe43411855aca2f719e505b051bc4b61b3Andreas Huber
13380a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    if (mFlags & CACHE_UNDERRUN) {
1339a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(CACHE_UNDERRUN, CLEAR);
13400a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber        play_l();
13410a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    }
13420a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
13435dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
13445dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        // Video playback completed before, there's no pending
13455dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        // video event right now. In order for this new seek
13465dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        // to be honored, we need to post one.
13475dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber
13485dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        postVideoEvent_l();
13495dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    }
13505dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber
135164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    mSeeking = SEEK;
13521321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber    mSeekNotificationSent = false;
1353bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mSeekTimeUs = timeUs;
1354a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
1355bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1356bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    seekAudioIfNecessary_l();
1357bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
13587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mFlags & TEXTPLAYER_STARTED) {
13597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer->seekTo(mSeekTimeUs);
13607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
13617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13621321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber    if (!(mFlags & PLAYING)) {
13631321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        LOGV("seeking while paused, sending SEEK_COMPLETE notification"
13641321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber             " immediately.");
13651321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber
13661321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        notifyListener_l(MEDIA_SEEK_COMPLETE);
13671321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        mSeekNotificationSent = true;
13682b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
13692b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        if ((mFlags & PREPARED) && mVideoSource != NULL) {
1370a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(SEEK_PREVIEW, SET);
13712b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            postVideoEvent_l();
13722b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        }
13731321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber    }
13741321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber
1375bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1376bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1377bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1378bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::seekAudioIfNecessary_l() {
137964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
1380bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        mAudioPlayer->seekTo(mSeekTimeUs);
1381bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
13821862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioSeekComplete = true;
13831862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioEOS = true;
1384dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
1385dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDecryptHandle != NULL) {
1386dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1387dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    Playback::PAUSE, 0);
1388dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1389dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    Playback::START, mSeekTimeUs / 1000);
1390dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
1391bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1392bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1393bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
139488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Hubervoid AwesomePlayer::setAudioSource(sp<MediaSource> source) {
139588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    CHECK(source != NULL);
1396bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
139788d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mAudioTrack = source;
139888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber}
139988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
14007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid AwesomePlayer::addTextSource(sp<MediaSource> source) {
1401965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    Mutex::Autolock autoLock(mTimedTextLock);
14027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(source != NULL);
14037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
14047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextPlayer == NULL) {
14057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
14067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
14077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
14087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextPlayer->addTextSource(source);
14097a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
14107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
141188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huberstatus_t AwesomePlayer::initAudioDecoder() {
141288d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    sp<MetaData> meta = mAudioTrack->getFormat();
1413717826ececd8d39596f62418677721d70776add1Andreas Huber
1414717826ececd8d39596f62418677721d70776add1Andreas Huber    const char *mime;
1415717826ececd8d39596f62418677721d70776add1Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
1416717826ececd8d39596f62418677721d70776add1Andreas Huber
1417717826ececd8d39596f62418677721d70776add1Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
141888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        mAudioSource = mAudioTrack;
1419717826ececd8d39596f62418677721d70776add1Andreas Huber    } else {
1420717826ececd8d39596f62418677721d70776add1Andreas Huber        mAudioSource = OMXCodec::Create(
142188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber                mClient.interface(), mAudioTrack->getFormat(),
1422717826ececd8d39596f62418677721d70776add1Andreas Huber                false, // createEncoder
142388d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber                mAudioTrack);
1424717826ececd8d39596f62418677721d70776add1Andreas Huber    }
1425bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1426bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mAudioSource != NULL) {
1427bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        int64_t durationUs;
142888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
14292415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber            Mutex::Autolock autoLock(mMiscStateLock);
1430bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (mDurationUs < 0 || durationUs > mDurationUs) {
1431bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                mDurationUs = durationUs;
1432bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
1433bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1434bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1435a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber        status_t err = mAudioSource->start();
1436a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber
1437a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber        if (err != OK) {
1438a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber            mAudioSource.clear();
1439a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber            return err;
1440a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber        }
144181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
144281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // For legacy reasons we're simply going to ignore the absence
144381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // of an audio decoder for QCELP instead of aborting playback
144481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // altogether.
144581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return OK;
144681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
1447e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber
1448a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mAudioSource != NULL) {
1449a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
1450a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
1451a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1452a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        const char *component;
1453a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        if (!mAudioSource->getFormat()
1454a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                ->findCString(kKeyDecoderComponent, &component)) {
1455a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            component = "none";
1456a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
1457a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1458a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        stat->mDecoderName = component;
1459a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
1460a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1461bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
1462bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1463bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
146488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Hubervoid AwesomePlayer::setVideoSource(sp<MediaSource> source) {
146588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    CHECK(source != NULL);
1466bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
146788d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mVideoTrack = source;
146888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber}
146988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
14702a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huberstatus_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
14712eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten
14722eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // Either the application or the DRM system can independently say
14732eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // that there must be a hardware-protected path to an external video sink.
14742eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // For now we always require a hardware-protected path to external video sink
14752eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // if content is DRMed, but eventually this could be optional per DRM agent.
14762eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // When the application wants protection, then
14772eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    //   (USE_SURFACE_ALLOC && (mSurface != 0) &&
14782eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    //   (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
14792eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // will be true, but that part is already handled by SurfaceFlinger.
1480eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten
1481eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#ifdef DEBUG_HDCP
1482eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // For debugging, we allow a system property to control the protected usage.
1483eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // In case of uninitialized or unexpected property, we default to "DRM only".
1484eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    bool setProtectionBit = false;
1485eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    char value[PROPERTY_VALUE_MAX];
1486eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    if (property_get("persist.sys.hdcp_checking", value, NULL)) {
1487eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        if (!strcmp(value, "never")) {
1488eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            // nop
1489eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        } else if (!strcmp(value, "always")) {
1490eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            setProtectionBit = true;
1491eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        } else if (!strcmp(value, "drm-only")) {
1492eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            if (mDecryptHandle != NULL) {
1493eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten                setProtectionBit = true;
1494eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            }
1495eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        // property value is empty, or unexpected value
1496eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        } else {
1497eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            if (mDecryptHandle != NULL) {
1498eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten                setProtectionBit = true;
1499eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            }
1500eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        }
1501eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // can' read property value
1502eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    } else {
1503eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        if (mDecryptHandle != NULL) {
1504eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            setProtectionBit = true;
1505eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        }
1506eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    }
1507eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // note that usage bit is already cleared, so no need to clear it in the "else" case
1508eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    if (setProtectionBit) {
1509eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        flags |= OMXCodec::kEnableGrallocUsageProtected;
1510eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    }
1511eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#else
15122eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    if (mDecryptHandle != NULL) {
15132eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten        flags |= OMXCodec::kEnableGrallocUsageProtected;
15142eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    }
1515eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#endif
15162eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    LOGV("initVideoDecoder flags=0x%x", flags);
1517bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoSource = OMXCodec::Create(
151888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber            mClient.interface(), mVideoTrack->getFormat(),
1519bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            false, // createEncoder
152039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mVideoTrack,
15211173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
1522bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1523bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoSource != NULL) {
1524bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        int64_t durationUs;
152588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
15262415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber            Mutex::Autolock autoLock(mMiscStateLock);
1527bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (mDurationUs < 0 || durationUs > mDurationUs) {
1528bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                mDurationUs = durationUs;
1529bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
1530bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1531bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1532139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        status_t err = mVideoSource->start();
1533139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber
1534139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        if (err != OK) {
1535139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber            mVideoSource.clear();
1536139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber            return err;
1537139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        }
1538bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1539bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1540a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mVideoSource != NULL) {
154114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        const char *componentName;
1542a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        CHECK(mVideoSource->getFormat()
154314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                ->findCString(kKeyDecoderComponent, &componentName));
1544a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
154514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        {
154614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            Mutex::Autolock autoLock(mStatsLock);
154714f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
154814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
154914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            stat->mDecoderName = componentName;
155014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        }
155114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
155214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        static const char *kPrefix = "OMX.Nvidia.";
155314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        static const char *kSuffix = ".decode";
155414f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        static const size_t kSuffixLength = strlen(kSuffix);
155514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
155614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        size_t componentNameLength = strlen(componentName);
155714f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
155814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        if (!strncmp(componentName, kPrefix, strlen(kPrefix))
155914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                && componentNameLength >= kSuffixLength
156014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                && !strcmp(&componentName[
156114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    componentNameLength - kSuffixLength], kSuffix)) {
156214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            modifyFlags(SLOW_DECODER_HACK, SET);
156314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        }
1564a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
1565a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1566bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
1567bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1568bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
15694769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Hubervoid AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
157064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking == SEEK_VIDEO_ONLY) {
157164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        mSeeking = NO_SEEK;
157264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        return;
157364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    }
157464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
157564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
15764769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        return;
15774769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    }
15784769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
15794769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    if (mAudioPlayer != NULL) {
1580f83dd80384f70da1f6d36d60e831439ff7739ad7Jamie Gennis        LOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
15814769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
15824769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // If we don't have a video time, seek audio to the originally
15834769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // requested seek time instead.
15844769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
15854769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
15864769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        mWatchForAudioSeekComplete = true;
15875dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        mWatchForAudioEOS = true;
15884769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    } else if (!mSeekNotificationSent) {
15894769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // If we're playing video only, report seek complete now,
15904769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // otherwise audio player will notify us later.
15914769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        notifyListener_l(MEDIA_SEEK_COMPLETE);
1592512895089f2035bc86d3f502255199809aca721bAndreas Huber        mSeekNotificationSent = true;
15934769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    }
15944769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
1595a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(FIRST_FRAME, SET);
159664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    mSeeking = NO_SEEK;
1597a89082944308805b0def7de87c67e370e74b8789Gloria Wang
1598a89082944308805b0def7de87c67e370e74b8789Gloria Wang    if (mDecryptHandle != NULL) {
1599a89082944308805b0def7de87c67e370e74b8789Gloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1600a89082944308805b0def7de87c67e370e74b8789Gloria Wang                Playback::PAUSE, 0);
1601a89082944308805b0def7de87c67e370e74b8789Gloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1602a89082944308805b0def7de87c67e370e74b8789Gloria Wang                Playback::START, videoTimeUs / 1000);
1603a89082944308805b0def7de87c67e370e74b8789Gloria Wang    }
16044769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber}
16054769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
1606c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Hubervoid AwesomePlayer::onVideoEvent() {
1607bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
16087b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    if (!mVideoEventPending) {
16097b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        // The event has been cancelled in reset_l() but had already
16107b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        // been scheduled for execution at that time.
16117b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        return;
16127b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    }
1613bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = false;
1614bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
161564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking != NO_SEEK) {
1616bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        if (mVideoBuffer) {
1617bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            mVideoBuffer->release();
1618bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            mVideoBuffer = NULL;
1619bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
16200a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1621681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
16222b1222f8938356669672f35e0e53e176c78c40efAndreas Huber                && !(mFlags & SEEK_PREVIEW)) {
16230a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // We're going to seek the video source first, followed by
16240a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // the audio source.
16250a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // In order to avoid jumps in the DataSource offset caused by
16260a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // the audio codec prefetching data from the old locations
16270a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // while the video codec is already reading data from the new
16280a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // locations, we'll "pause" the audio source, causing it to
16290a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // stop reading input data until a subsequent seek.
16300a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1631f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
16320a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber                mAudioPlayer->pause();
1633f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
1634a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(AUDIO_RUNNING, CLEAR);
16350a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            }
16360a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            mAudioSource->pause();
16370a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber        }
1638bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1639bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1640bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (!mVideoBuffer) {
1641bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        MediaSource::ReadOptions options;
164264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (mSeeking != NO_SEEK) {
1643bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
1644bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1645abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            options.setSeekTo(
164664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                    mSeekTimeUs,
164764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                    mSeeking == SEEK_VIDEO_ONLY
164864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
164964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
1650bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1651bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        for (;;) {
1652bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            status_t err = mVideoSource->read(&mVideoBuffer, &options);
1653c1689e49ac867de33f2e81289449878ac2e536a0Andreas Huber            options.clearSeekTo();
1654bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1655bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (err != OK) {
1656e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                CHECK(mVideoBuffer == NULL);
1657bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1658bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                if (err == INFO_FORMAT_CHANGED) {
1659bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                    LOGV("VideoSource signalled format change.");
1660bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
16615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    notifyVideoSize_l();
16625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1663a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber                    if (mVideoRenderer != NULL) {
1664fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber                        mVideoRendererIsPreview = false;
1665a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber                        initRenderer_l();
1666a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber                    }
1667bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                    continue;
1668bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                }
1669bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
16704769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                // So video playback is complete, but we may still have
16714769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                // a seek request pending that needs to be applied
16724769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                // to the audio track.
167364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                if (mSeeking != NO_SEEK) {
16744769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                    LOGV("video stream ended while seeking!");
16754769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                }
16764769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                finishSeekIfNecessary(-1);
16774769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
16785dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                if (mAudioPlayer != NULL
16795dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                        && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
16805dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                    startAudioPlayer_l();
16815dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                }
16825dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber
1683a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(VIDEO_AT_EOS, SET);
16845295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                postStreamDoneEvent_l(err);
1685bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                return;
1686bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
1687bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
16884844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber            if (mVideoBuffer->range_length() == 0) {
168908411b75d4c30ce26180639f158e2f33d190eee8Andreas Huber                // Some decoders, notably the PV AVC software decoder
169008411b75d4c30ce26180639f158e2f33d190eee8Andreas Huber                // return spurious empty buffers that we just want to ignore.
169108411b75d4c30ce26180639f158e2f33d190eee8Andreas Huber
16924844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber                mVideoBuffer->release();
16934844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber                mVideoBuffer = NULL;
16944844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber                continue;
16954844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber            }
16964844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber
1697bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            break;
1698bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1699a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1700a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        {
1701a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            Mutex::Autolock autoLock(mStatsLock);
1702a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            ++mStats.mNumVideoFramesDecoded;
1703a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
1704bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1705bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1706bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    int64_t timeUs;
1707bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1708bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1709150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mLastVideoTimeUs = timeUs;
1710150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
171164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking == SEEK_VIDEO_ONLY) {
171264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (mSeekTimeUs > timeUs) {
171364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
171464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                 mSeekTimeUs, timeUs);
171564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        }
171664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    }
171764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
17182415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    {
17192415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber        Mutex::Autolock autoLock(mMiscStateLock);
17202415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber        mVideoTimeUs = timeUs;
17212415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    }
1722bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
172364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    SeekType wasSeeking = mSeeking;
17244769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    finishSeekIfNecessary(timeUs);
1725bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1726f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1727f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        status_t err = startAudioPlayer_l();
1728f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        if (err != OK) {
17295442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            LOGE("Starting the audio player failed w/ err %d", err);
1730f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            return;
1731f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        }
1732f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    }
1733f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
17347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
17357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer->resume();
1736a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(TEXT_RUNNING, SET);
17377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
17387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1739f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    TimeSource *ts =
1740f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber        ((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
1741f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber            ? &mSystemTimeSource : mTimeSource;
17425d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
1743bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mFlags & FIRST_FRAME) {
1744a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(FIRST_FRAME, CLEAR);
174514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        mSinceLastDropped = 0;
17465d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
1747bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1748bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1749bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    int64_t realTimeUs, mediaTimeUs;
17505d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
1751bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
1752bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
1753bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1754bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
175564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (wasSeeking == SEEK_VIDEO_ONLY) {
175664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
175764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
175864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        int64_t latenessUs = nowUs - timeUs;
175964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
176064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (latenessUs > 0) {
176164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
176264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        }
176364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    }
176464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
176564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (wasSeeking == NO_SEEK) {
176602a1db7dc1de2f2df306ec10bab992bc8bbaaca8Andreas Huber        // Let's display the first frame after seeking right away.
1767f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
17682b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1769bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
17702b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        int64_t latenessUs = nowUs - timeUs;
17712b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
177264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (latenessUs > 500000ll
177364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                && mRTSPController == NULL
177464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                && mAudioPlayer != NULL
177564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                && mAudioPlayer->getMediaTimeMapping(
177664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                    &realTimeUs, &mediaTimeUs)) {
177764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            LOGI("we're much too late (%.2f secs), video skipping ahead",
177864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                 latenessUs / 1E6);
177964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
178064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mVideoBuffer->release();
178164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mVideoBuffer = NULL;
178264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
178364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mSeeking = SEEK_VIDEO_ONLY;
178464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mSeekTimeUs = mediaTimeUs;
178564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
178664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            postVideoEvent_l();
178764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            return;
178864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        }
178964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
17902b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        if (latenessUs > 40000) {
17912b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            // We're more than 40ms late.
179214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            LOGV("we're late by %lld us (%.2f secs)",
1793dab59b5a4956b7e9b1ffc64a0676e7990579934eAndreas Huber                 latenessUs, latenessUs / 1E6);
17942b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
179514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            if (!(mFlags & SLOW_DECODER_HACK)
179614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    || mSinceLastDropped > FRAME_DROP_FREQ)
1797a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            {
179814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                LOGV("we're late by %lld us (%.2f secs) dropping "
179914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                     "one after %d frames",
180014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                     latenessUs, latenessUs / 1E6, mSinceLastDropped);
1801a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
180214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                mSinceLastDropped = 0;
180314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                mVideoBuffer->release();
180414f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                mVideoBuffer = NULL;
180514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
180614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                {
180714f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    Mutex::Autolock autoLock(mStatsLock);
180814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    ++mStats.mNumVideoFramesDropped;
180914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                }
181014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
181114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                postVideoEvent_l();
181214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                return;
181314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            }
1814aee6c07b3572bf2510cd9e7d29c454fcfedde31dpmehendale        }
1815bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
18162b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        if (latenessUs < -10000) {
18172b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            // We're more than 10ms early.
1818bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
18192b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            postVideoEvent_l(10000);
18202b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            return;
18212b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        }
1822bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1823bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
182480ec929862bcfe8582984f3a28e7a4ca5f4f27bbGloria Wang    if ((mNativeWindow != NULL)
182580ec929862bcfe8582984f3a28e7a4ca5f4f27bbGloria Wang            && (mVideoRendererIsPreview || mVideoRenderer == NULL)) {
1826fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber        mVideoRendererIsPreview = false;
1827fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber
1828a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        initRenderer_l();
1829a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber    }
1830a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber
1831a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber    if (mVideoRenderer != NULL) {
183214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        mSinceLastDropped++;
1833a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        mVideoRenderer->render(mVideoBuffer);
1834a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber    }
1835bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1836f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    mVideoBuffer->release();
1837bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoBuffer = NULL;
1838bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
183964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
1840a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(SEEK_PREVIEW, CLEAR);
18412b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        return;
18422b1222f8938356669672f35e0e53e176c78c40efAndreas Huber    }
18432b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
1844bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    postVideoEvent_l();
1845bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1846bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1847bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
1848bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoEventPending) {
1849bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return;
1850bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1851bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1852bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = true;
1853bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
1854bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1855bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
18565295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Hubervoid AwesomePlayer::postStreamDoneEvent_l(status_t status) {
1857bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mStreamDoneEventPending) {
1858bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return;
1859bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1860bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = true;
18615295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber
18625295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    mStreamDoneStatus = status;
1863bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.postEvent(mStreamDoneEvent);
1864bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1865bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
186666b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Hubervoid AwesomePlayer::postBufferingEvent_l() {
186766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    if (mBufferingEventPending) {
186866b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        return;
186966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
187066b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mBufferingEventPending = true;
187166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
187266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber}
187366b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
1874145e68fc778275963189b02a1adcbe27cce4d769Andreas Hubervoid AwesomePlayer::postVideoLagEvent_l() {
1875145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    if (mVideoLagEventPending) {
1876145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        return;
1877145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    }
1878145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEventPending = true;
1879145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
1880145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber}
1881145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
188202f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Hubervoid AwesomePlayer::postCheckAudioStatusEvent(int64_t delayUs) {
188302f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    Mutex::Autolock autoLock(mAudioLock);
18841862a33b246249630b654182afb5914da3480d4cAndreas Huber    if (mAudioStatusEventPending) {
18851862a33b246249630b654182afb5914da3480d4cAndreas Huber        return;
18861862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
18871862a33b246249630b654182afb5914da3480d4cAndreas Huber    mAudioStatusEventPending = true;
188884b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
18891862a33b246249630b654182afb5914da3480d4cAndreas Huber}
18901862a33b246249630b654182afb5914da3480d4cAndreas Huber
18911862a33b246249630b654182afb5914da3480d4cAndreas Hubervoid AwesomePlayer::onCheckAudioStatus() {
189202f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    {
189302f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        Mutex::Autolock autoLock(mAudioLock);
189402f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        if (!mAudioStatusEventPending) {
189502f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            // Event was dispatched and while we were blocking on the mutex,
189602f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            // has already been cancelled.
189702f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            return;
189802f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        }
189902f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber
190002f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        mAudioStatusEventPending = false;
1901d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    }
1902d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber
190302f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    Mutex::Autolock autoLock(mLock);
19041862a33b246249630b654182afb5914da3480d4cAndreas Huber
19051862a33b246249630b654182afb5914da3480d4cAndreas Huber    if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
19061862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioSeekComplete = false;
19071321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber
19081321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        if (!mSeekNotificationSent) {
19091321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber            notifyListener_l(MEDIA_SEEK_COMPLETE);
19101321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber            mSeekNotificationSent = true;
19111321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        }
1912dac4ee72bac87388a1495e098f39d73168c8078fAndreas Huber
191364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        mSeeking = NO_SEEK;
19141862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
19151862a33b246249630b654182afb5914da3480d4cAndreas Huber
19165295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    status_t finalStatus;
19175295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
19181862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioEOS = false;
1919a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AUDIO_AT_EOS, SET);
1920a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(FIRST_FRAME, SET);
19215295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber        postStreamDoneEvent_l(finalStatus);
19221862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
19231862a33b246249630b654182afb5914da3480d4cAndreas Huber}
19241862a33b246249630b654182afb5914da3480d4cAndreas Huber
1925c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huberstatus_t AwesomePlayer::prepare() {
1926c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    Mutex::Autolock autoLock(mLock);
1927bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    return prepare_l();
1928bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber}
1929c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1930bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huberstatus_t AwesomePlayer::prepare_l() {
1931bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARED) {
1932bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return OK;
1933bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
1934bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1935bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARING) {
1936bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;
1937bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
1938bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1939bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mIsAsyncPrepare = false;
1940c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    status_t err = prepareAsync_l();
1941c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1942c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    if (err != OK) {
1943c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber        return err;
1944c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
1945c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1946bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    while (mFlags & PREPARING) {
1947c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber        mPreparedCondition.wait(mLock);
1948c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
1949c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1950bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    return mPrepareResult;
1951c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
1952c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1953c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huberstatus_t AwesomePlayer::prepareAsync() {
1954c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    Mutex::Autolock autoLock(mLock);
1955bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1956bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARING) {
1957bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;  // async prepare already pending
1958bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
1959bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1960bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mIsAsyncPrepare = true;
1961c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    return prepareAsync_l();
1962c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
1963c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1964c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huberstatus_t AwesomePlayer::prepareAsync_l() {
1965bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARING) {
1966bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;  // async prepare already pending
1967c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
1968c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
19692e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    if (!mQueueStarted) {
19702e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        mQueue.start();
19712e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        mQueueStarted = true;
19722e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    }
19732e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
1974a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PREPARING, SET);
1975c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mAsyncPrepareEvent = new AwesomeEvent(
1976c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            this, &AwesomePlayer::onPrepareAsyncEvent);
1977c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1978c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mQueue.postEvent(mAsyncPrepareEvent);
1979c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1980c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    return OK;
1981c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
1982c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1983bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huberstatus_t AwesomePlayer::finishSetDataSource_l() {
1984e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    sp<DataSource> dataSource;
1985e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
1986681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    bool isWidevineStreaming = false;
1987681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (!strncasecmp("widevine://", mUri.string(), 11)) {
1988681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        isWidevineStreaming = true;
1989681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
1990681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        String8 newURI = String8("http://");
1991681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        newURI.append(mUri.string() + 11);
1992681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
1993681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mUri = newURI;
1994681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    }
1995681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
19968cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber    if (!strncasecmp("http://", mUri.string(), 7)
1997681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            || !strncasecmp("https://", mUri.string(), 8)
1998681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            || isWidevineStreaming) {
19991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mConnectingDataSource = HTTPBase::Create(
20001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                (mFlags & INCOGNITO)
20011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    ? HTTPBase::kFlagIncognito
20021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    : 0);
2003e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
20049b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        if (mUIDValid) {
20059b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber            mConnectingDataSource->setUID(mUID);
20069b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        }
20079b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
200849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber        String8 cacheConfig;
200949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber        bool disconnectAtHighwatermark;
201049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber        NuCachedSource2::RemoveCacheSpecificHeaders(
201149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
201249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber
2013e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mLock.unlock();
201479f77ef3b0a37660ba8c5bcb2dfbfda3860f2135Andreas Huber        status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
2015e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mLock.lock();
2016e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
2017e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        if (err != OK) {
2018e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            mConnectingDataSource.clear();
2019e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
2020e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            LOGI("mConnectingDataSource->connect() returned %d", err);
2021e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            return err;
2022e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        }
2023e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
2024681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (!isWidevineStreaming) {
2025681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            // The widevine extractor does its own caching.
2026681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
20270a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#if 0
2028681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            mCachedSource = new NuCachedSource2(
2029681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                    new ThrottledSource(
2030681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                        mConnectingDataSource, 50 * 1024 /* bytes/sec */));
20310a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#else
203249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            mCachedSource = new NuCachedSource2(
203349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                    mConnectingDataSource,
203449c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                    cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
203549c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                    disconnectAtHighwatermark);
20360a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#endif
2037681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2038681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            dataSource = mCachedSource;
2039681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        } else {
2040681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            dataSource = mConnectingDataSource;
2041681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
2042681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2043e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mConnectingDataSource.clear();
20440a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
2045ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
20466511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber        String8 contentType = dataSource->getMIMEType();
2047ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
20486511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber        if (strncasecmp(contentType.string(), "audio/", 6)) {
20496511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // We're not doing this for streams that appear to be audio-only
20506511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // streams to ensure that even low bandwidth streams start
20516511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // playing back fairly instantly.
2052ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
20536511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // We're going to prefill the cache before trying to instantiate
20546511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // the extractor below, as the latter is an operation that otherwise
20556511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // could block on the datasource for a significant amount of time.
20566511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // During that time we'd be unable to abort the preparation phase
20576511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // without this prefill.
2058e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong            if (mCachedSource != NULL) {
2059e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // We're going to prefill the cache before trying to instantiate
2060e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // the extractor below, as the latter is an operation that otherwise
2061e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // could block on the datasource for a significant amount of time.
2062e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // During that time we'd be unable to abort the preparation phase
2063e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // without this prefill.
2064e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong
2065e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                mLock.unlock();
2066e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong
2067e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                for (;;) {
2068e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    status_t finalStatus;
2069e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    size_t cachedDataRemaining =
2070e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                        mCachedSource->approxDataRemaining(&finalStatus);
2071e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong
2072e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
2073e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                            || (mFlags & PREPARE_CANCELLED)) {
2074e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                        break;
2075e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    }
20766511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
2077e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    usleep(200000);
20786511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber                }
20796511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
2080e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                mLock.lock();
2081ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber            }
2082ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
2083e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong            if (mFlags & PREPARE_CANCELLED) {
2084e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                LOGI("Prepare cancelled while waiting for initial cache fill.");
2085e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                return UNKNOWN_ERROR;
2086e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong            }
2087ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber        }
2088cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
2089cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (mLooper == NULL) {
2090cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            mLooper = new ALooper;
2091a814c1fdc2acf0ed2ee3b175110f6039be7c4873Andreas Huber            mLooper->setName("rtsp");
2092cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            mLooper->start();
2093cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
2094cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mRTSPController = new ARTSPController(mLooper);
2095f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber        mConnectingRTSPController = mRTSPController;
2096f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber
20979b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        if (mUIDValid) {
20989b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber            mConnectingRTSPController->setUID(mUID);
20999b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        }
21009b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2101f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber        mLock.unlock();
2102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        status_t err = mRTSPController->connect(mUri.string());
2103f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber        mLock.lock();
2104f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber
2105f1958f9442bc937e1f8c8d9175901500b944b021Andreas Huber        mConnectingRTSPController.clear();
2106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        LOGI("ARTSPController::connect returned %d", err);
2108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (err != OK) {
2110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            mRTSPController.clear();
2111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return err;
2112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
2113e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber
2114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<MediaExtractor> extractor = mRTSPController.get();
2115e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber        return setDataSource_l(extractor);
2116e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    } else {
2117e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
2118e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    }
2119bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2120bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (dataSource == NULL) {
2121bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;
2122bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
2123bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2124681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    sp<MediaExtractor> extractor;
2125bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2126681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (isWidevineStreaming) {
2127681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        String8 mimeType;
2128681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        float confidence;
2129681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        sp<AMessage> dummy;
2130681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy);
2131681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2132681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (!success
2133681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                || strcasecmp(
2134681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
2135681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            return ERROR_UNSUPPORTED;
2136681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
2137681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2138681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mWVMExtractor = new WVMExtractor(dataSource);
2139681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mWVMExtractor->setAdaptiveStreamingMode(true);
2140681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        extractor = mWVMExtractor;
2141681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    } else {
2142681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        extractor = MediaExtractor::Create(dataSource);
2143681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2144681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (extractor == NULL) {
2145681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            return UNKNOWN_ERROR;
2146681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
2147bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
2148bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2149b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
2150b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang
2151b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang    if (mDecryptHandle != NULL) {
21528f64134f749e4f7861a08a3063450fc714c4651dGloria Wang        CHECK(mDrmManagerClient);
21533318523222e31fb4a7fcc345ddb4ec845d30ef96James Dong        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
21547340743ce30766af6334bbd9acf813eb66dd5a60Gloria Wang            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2155b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang        }
2156dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
2157dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2158681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    status_t err = setDataSource_l(extractor);
2159681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2160681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (err != OK) {
2161681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mWVMExtractor.clear();
2162681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2163681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        return err;
2164681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    }
2165681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2166681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    return OK;
2167bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber}
2168bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
216988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Hubervoid AwesomePlayer::abortPrepare(status_t err) {
217088d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    CHECK(err != OK);
217188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
217288d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    if (mIsAsyncPrepare) {
217388d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
217488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    }
217588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
217688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mPrepareResult = err;
2177a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
217888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mAsyncPrepareEvent = NULL;
217988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mPreparedCondition.broadcast();
218088d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber}
218188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
2182e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber// static
2183e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huberbool AwesomePlayer::ContinuePreparation(void *cookie) {
2184e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber    AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
2185e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber
2186e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber    return (me->mFlags & PREPARE_CANCELLED) == 0;
2187e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber}
2188e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber
2189c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Hubervoid AwesomePlayer::onPrepareAsyncEvent() {
21908650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    Mutex::Autolock autoLock(mLock);
2191bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
21928650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mFlags & PREPARE_CANCELLED) {
21938650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        LOGI("prepare was cancelled before doing anything");
21948650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        abortPrepare(UNKNOWN_ERROR);
21958650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        return;
21968650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
2197e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
21988650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mUri.size() > 0) {
21998650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        status_t err = finishSetDataSource_l();
2200bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
22018650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (err != OK) {
22028650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            abortPrepare(err);
22038650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            return;
2204bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        }
22058650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
2206bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
22078650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mVideoTrack != NULL && mVideoSource == NULL) {
22088650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        status_t err = initVideoDecoder();
22091322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber
22108650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (err != OK) {
22118650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            abortPrepare(err);
22128650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            return;
22131322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber        }
22148650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
22151322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber
22168650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mAudioTrack != NULL && mAudioSource == NULL) {
22178650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        status_t err = initAudioDecoder();
22181322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber
22198650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (err != OK) {
22208650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            abortPrepare(err);
22218650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            return;
22221322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber        }
2223c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
2224c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2225a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PREPARING_CONNECTED, SET);
22266a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber
2227681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (isStreamingHTTP() || mRTSPController != NULL) {
22288650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        postBufferingEvent_l();
22298650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    } else {
22308650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        finishAsyncPrepare_l();
22318650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
22328650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber}
2233c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
22348650e1960905097f6f1d6aa462ccb1c93c656834Andreas Hubervoid AwesomePlayer::finishAsyncPrepare_l() {
2235bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mIsAsyncPrepare) {
22365daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        if (mVideoSource == NULL) {
2237bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
2238bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        } else {
22395daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            notifyVideoSize_l();
2240bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        }
2241c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2242bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        notifyListener_l(MEDIA_PREPARED);
2243bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
2244c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2245bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mPrepareResult = OK;
2246a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
2247a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PREPARED, SET);
2248c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mAsyncPrepareEvent = NULL;
2249bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mPreparedCondition.broadcast();
2250c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
2251c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2252acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huberuint32_t AwesomePlayer::flags() const {
2253acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    return mExtractorFlags;
2254acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber}
2255acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
225684b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Hubervoid AwesomePlayer::postAudioEOS(int64_t delayUs) {
225702f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    postCheckAudioStatusEvent(delayUs);
2258ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber}
2259ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
2260ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Hubervoid AwesomePlayer::postAudioSeekComplete() {
226102f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    postCheckAudioStatusEvent(0);
2262ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber}
2263ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
22644f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t AwesomePlayer::setParameter(int key, const Parcel &request) {
2265965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    switch (key) {
2266965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        case KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX:
2267965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        {
2268965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            Mutex::Autolock autoLock(mTimedTextLock);
2269965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return setTimedTextTrackIndex(request.readInt32());
2270965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
2271965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE:
2272965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        {
2273965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            Mutex::Autolock autoLock(mTimedTextLock);
2274965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            if (mTextPlayer == NULL) {
2275965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
2276965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            }
2277965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
2278965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return mTextPlayer->setParameter(key, request);
2279965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
22805b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
22815b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        {
22825b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            return setCacheStatCollectFreq(request);
22835b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        }
2284965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        default:
2285965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        {
2286965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return ERROR_UNSUPPORTED;
2287965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
22887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
22894f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
22904f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang
22915b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t AwesomePlayer::setCacheStatCollectFreq(const Parcel &request) {
22925b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    if (mCachedSource != NULL) {
22935b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        int32_t freqMs = request.readInt32();
22945b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        LOGD("Request to keep cache stats in the past %d ms",
22955b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            freqMs);
22965b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        return mCachedSource->setCacheStatCollectFreq(freqMs);
22975b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
22985b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    return ERROR_UNSUPPORTED;
22995b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
23005b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
23014f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t AwesomePlayer::getParameter(int key, Parcel *reply) {
2302cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    switch (key) {
2303cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
2304cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        {
2305cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            int32_t channelCount;
2306cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            if (mAudioTrack == 0 ||
2307cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten                    !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
2308cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten                channelCount = 0;
2309cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            }
2310cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            reply->writeInt32(channelCount);
2311cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        }
2312cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        return OK;
2313cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    default:
2314cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        {
2315cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            return ERROR_UNSUPPORTED;
2316cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        }
2317cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    }
23184f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
2319ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
2320681755fc0d0797506456f46a2a10555916d6be32Andreas Huberbool AwesomePlayer::isStreamingHTTP() const {
2321681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    return mCachedSource != NULL || mWVMExtractor != NULL;
2322681755fc0d0797506456f46a2a10555916d6be32Andreas Huber}
2323681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2324a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huberstatus_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
2325a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    Mutex::Autolock autoLock(mStatsLock);
2326a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2327a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    FILE *out = fdopen(dup(fd), "w");
2328a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2329a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fprintf(out, " AwesomePlayer\n");
2330a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mStats.mFd < 0) {
2331a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "  URI(%s)", mStats.mURI.string());
2332a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    } else {
2333a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "  fd(%d)", mStats.mFd);
2334a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2335a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2336a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fprintf(out, ", flags(0x%08x)", mStats.mFlags);
2337a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2338a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mStats.mBitrate >= 0) {
2339a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate);
2340a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2341a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2342a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fprintf(out, "\n");
2343a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2344a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
2345a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        const TrackStat &stat = mStats.mTracks.itemAt(i);
2346a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2347a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "  Track %d\n", i + 1);
2348a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "   MIME(%s)", stat.mMIME.string());
2349a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2350a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        if (!stat.mDecoderName.isEmpty()) {
2351a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            fprintf(out, ", decoder(%s)", stat.mDecoderName.string());
2352a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
2353a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2354a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "\n");
2355a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2356a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        if ((ssize_t)i == mStats.mVideoTrackIndex) {
2357a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            fprintf(out,
2358a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    "   videoDimensions(%d x %d), "
2359a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    "numVideoFramesDecoded(%lld), "
2360a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    "numVideoFramesDropped(%lld)\n",
2361a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mVideoWidth,
2362a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mVideoHeight,
2363a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mNumVideoFramesDecoded,
2364a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mNumVideoFramesDropped);
2365a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
2366a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2367a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2368a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fclose(out);
2369a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    out = NULL;
2370a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2371a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    return OK;
2372a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber}
2373a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2374a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Hubervoid AwesomePlayer::modifyFlags(unsigned value, FlagMode mode) {
2375a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    switch (mode) {
2376a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        case SET:
2377a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            mFlags |= value;
2378a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            break;
2379a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        case CLEAR:
2380a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            mFlags &= ~value;
2381a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            break;
2382a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        case ASSIGN:
2383a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            mFlags = value;
2384a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            break;
2385a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        default:
2386a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            TRESPASS();
2387a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2388a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2389a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
2390a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
2391a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFlags = mFlags;
2392a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2393a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber}
2394a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2395bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}  // namespace android
2396