AwesomePlayer.cpp revision 29357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47
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
25bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include "include/AwesomePlayer.h"
26681755fc0d0797506456f46a2a10555916d6be32Andreas Huber#include "include/DRMExtractor.h"
27733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber#include "include/SoftwareRenderer.h"
280a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#include "include/NuCachedSource2.h"
290a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#include "include/ThrottledSource.h"
30bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber#include "include/MPEG2TSExtractor.h"
31681755fc0d0797506456f46a2a10555916d6be32Andreas Huber#include "include/WVMExtractor.h"
32bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
33965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include "timedtext/TimedTextPlayer.h"
34965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
354844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber#include <binder/IPCThreadState.h>
367cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang#include <binder/IServiceManager.h>
377cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang#include <media/IMediaPlayerService.h>
38e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/hexdump.h>
39e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/ADebug.h>
40bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/AudioPlayer.h>
41bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/DataSource.h>
42bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/FileSource.h>
43bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MediaBuffer.h>
44717826ececd8d39596f62418677721d70776add1Andreas Huber#include <media/stagefright/MediaDefs.h>
45bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MediaExtractor.h>
46bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MediaSource.h>
47bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/MetaData.h>
48bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber#include <media/stagefright/OMXCodec.h>
49717826ececd8d39596f62418677721d70776add1Andreas Huber
505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <surfaceflinger/Surface.h>
511173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h>
521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/SurfaceTextureClient.h>
532eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten#include <surfaceflinger/ISurfaceComposer.h>
543cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian
5514acc736e336cbd6026df781d4f411e908831815Andreas Huber#include <media/stagefright/foundation/AMessage.h>
56e71d10e7ad55ccbcb0756c007caef1c959090384Andreas Huber
57eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#include <cutils/properties.h>
58eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten
59e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber#define USE_SURFACE_ALLOC 1
6014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong#define FRAME_DROP_FREQ 0
61e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber
62bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubernamespace android {
63bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
648650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huberstatic int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
6583ed9d41b5aea53a5f3f0ae2fa14e101c079a12aGloria Wangstatic int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
66ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huberstatic const size_t kLowWaterMarkBytes = 40000;
67ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huberstatic const size_t kHighWaterMarkBytes = 200000;
688650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
69bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstruct AwesomeEvent : public TimedEventQueue::Event {
70c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    AwesomeEvent(
71c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            AwesomePlayer *player,
72c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            void (AwesomePlayer::*method)())
73bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        : mPlayer(player),
74c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber          mMethod(method) {
75bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
76bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
77bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberprotected:
78bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    virtual ~AwesomeEvent() {}
79bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
80bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
81c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber        (mPlayer->*mMethod)();
82bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
83bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
84bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberprivate:
85bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    AwesomePlayer *mPlayer;
86c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    void (AwesomePlayer::*mMethod)();
87bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
88bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    AwesomeEvent(const AwesomeEvent &);
89bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    AwesomeEvent &operator=(const AwesomeEvent &);
90bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber};
91bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
92733b7729ea462fae9c6899456444e28fef1c757cAndreas Huberstruct AwesomeLocalRenderer : public AwesomeRenderer {
93733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    AwesomeLocalRenderer(
941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
96733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    }
97733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
98733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    virtual void render(MediaBuffer *buffer) {
99fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber        render((const uint8_t *)buffer->data() + buffer->range_offset(),
100fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber               buffer->range_length());
101fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber    }
102fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber
103fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber    void render(const void *data, size_t size) {
104fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber        mTarget->render(data, size, NULL);
105733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    }
106733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
107733b7729ea462fae9c6899456444e28fef1c757cAndreas Huberprotected:
108733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    virtual ~AwesomeLocalRenderer() {
109733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber        delete mTarget;
110733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber        mTarget = NULL;
111733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    }
112733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
113733b7729ea462fae9c6899456444e28fef1c757cAndreas Huberprivate:
1140a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    SoftwareRenderer *mTarget;
115988e3f0b2c74095deae580157c57935a98573052Andreas Huber
116733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    AwesomeLocalRenderer(const AwesomeLocalRenderer &);
117733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber    AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
118733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber};
119733b7729ea462fae9c6899456444e28fef1c757cAndreas Huber
1206a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennisstruct AwesomeNativeWindowRenderer : public AwesomeRenderer {
121ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    AwesomeNativeWindowRenderer(
122ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            const sp<ANativeWindow> &nativeWindow,
123ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            int32_t rotationDegrees)
1246a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        : mNativeWindow(nativeWindow) {
125ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        applyRotation(rotationDegrees);
1266a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    }
1276a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1286a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    virtual void render(MediaBuffer *buffer) {
129593e2773f616a926af45e74359e21a898c89875fGlenn Kasten        int64_t timeUs;
130593e2773f616a926af45e74359e21a898c89875fGlenn Kasten        CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
131593e2773f616a926af45e74359e21a898c89875fGlenn Kasten        native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
1326a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        status_t err = mNativeWindow->queueBuffer(
1336a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis                mNativeWindow.get(), buffer->graphicBuffer().get());
1346a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        if (err != 0) {
13529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("queueBuffer failed with error %s (%d)", strerror(-err),
1366a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis                    -err);
1376a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis            return;
1386a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        }
1396a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1406a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        sp<MetaData> metaData = buffer->meta_data();
1416a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis        metaData->setInt32(kKeyRendered, 1);
1426a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    }
1436a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1446a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennisprotected:
1456a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    virtual ~AwesomeNativeWindowRenderer() {}
1466a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1476a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennisprivate:
1486a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    sp<ANativeWindow> mNativeWindow;
1496a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
150ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    void applyRotation(int32_t rotationDegrees) {
151ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        uint32_t transform;
152ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        switch (rotationDegrees) {
153ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 0: transform = 0; break;
154ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 90: transform = HAL_TRANSFORM_ROT_90; break;
155ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 180: transform = HAL_TRANSFORM_ROT_180; break;
156ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            case 270: transform = HAL_TRANSFORM_ROT_270; break;
157ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            default: transform = 0; break;
158ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        }
159ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
160ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        if (transform) {
161ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber            CHECK_EQ(0, native_window_set_buffers_transform(
162ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                        mNativeWindow.get(), transform));
163ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        }
164ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
165ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1666a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);
1676a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    AwesomeNativeWindowRenderer &operator=(
1686a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis            const AwesomeNativeWindowRenderer &);
1696a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis};
1706a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
1717cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang// To collect the decoder usage
1727cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wangvoid addBatteryData(uint32_t params) {
1737cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    sp<IBinder> binder =
1747cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        defaultServiceManager()->getService(String16("media.player"));
1757cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
1767cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    CHECK(service.get() != NULL);
1777cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
1787cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    service->addBatteryData(params);
1797cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang}
180e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
1817cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang////////////////////////////////////////////////////////////////////////////////
182bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas HuberAwesomePlayer::AwesomePlayer()
1832e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    : mQueueStarted(false),
1849b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber      mUIDValid(false),
1852e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber      mTimeSource(NULL),
186fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber      mVideoRendererIsPreview(false),
187bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber      mAudioPlayer(NULL),
188b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong      mDisplayWidth(0),
189b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong      mDisplayHeight(0),
190bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber      mFlags(0),
191acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber      mExtractorFlags(0),
1927b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber      mVideoBuffer(NULL),
193150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber      mDecryptHandle(NULL),
1947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mLastVideoTimeUs(-1),
1957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mTextPlayer(NULL) {
196e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(mClient.connect(), (status_t)OK);
197bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
198bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    DataSource::RegisterDefaultSniffers();
199bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
200c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
201bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = false;
202c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
203bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = false;
204c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
20566b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mBufferingEventPending = false;
206145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate);
207145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoEventPending = false;
208c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
209c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mCheckAudioStatusEvent = new AwesomeEvent(
210c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            this, &AwesomePlayer::onCheckAudioStatus);
211c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2121862a33b246249630b654182afb5914da3480d4cAndreas Huber    mAudioStatusEventPending = false;
213bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
214bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset();
215bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
216bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
217bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas HuberAwesomePlayer::~AwesomePlayer() {
2182e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    if (mQueueStarted) {
2192e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        mQueue.stop();
2202e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    }
221bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
222bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset();
223bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
224bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mClient.disconnect();
225bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
226bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
227c34233e673c9791e137456d0c427d58db184b690Andreas Hubervoid AwesomePlayer::cancelPlayerEvents(bool keepNotifications) {
228bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.cancelEvent(mVideoEvent->eventID());
229bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = false;
230145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mQueue.cancelEvent(mVideoLagEvent->eventID());
231145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEventPending = false;
23266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
233c34233e673c9791e137456d0c427d58db184b690Andreas Huber    if (!keepNotifications) {
234c34233e673c9791e137456d0c427d58db184b690Andreas Huber        mQueue.cancelEvent(mStreamDoneEvent->eventID());
235c34233e673c9791e137456d0c427d58db184b690Andreas Huber        mStreamDoneEventPending = false;
236c34233e673c9791e137456d0c427d58db184b690Andreas Huber        mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
237c34233e673c9791e137456d0c427d58db184b690Andreas Huber        mAudioStatusEventPending = false;
238c34233e673c9791e137456d0c427d58db184b690Andreas Huber
23966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        mQueue.cancelEvent(mBufferingEvent->eventID());
24066b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        mBufferingEventPending = false;
24166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
242bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
243bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
2440726045216f576e97672ebeefc265d39c4ebaaa5Andreas Hubervoid AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
245bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
246bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mListener = listener;
247bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
248bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
2499b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervoid AwesomePlayer::setUID(uid_t uid) {
2503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AwesomePlayer running on behalf of uid %d", uid);
2519b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2529b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
2539b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUIDValid = true;
2549b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber}
2559b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2565561ccf4a8db88a2e44eac1b3ed13b4ff53a7f20Andreas Huberstatus_t AwesomePlayer::setDataSource(
2575561ccf4a8db88a2e44eac1b3ed13b4ff53a7f20Andreas Huber        const char *uri, const KeyedVector<String8, String8> *headers) {
258bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
2597b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    return setDataSource_l(uri, headers);
2607b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber}
261bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
2627b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huberstatus_t AwesomePlayer::setDataSource_l(
2637b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        const char *uri, const KeyedVector<String8, String8> *headers) {
264bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset_l();
265bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
266bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mUri = uri;
26766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
268bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (headers) {
269bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        mUriHeaders = *headers;
2707314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
2717314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
2727314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        if (index >= 0) {
2737314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber            // Browser is in "incognito" mode, suppress logging URLs.
2747314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
2757314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber            // This isn't something that should be passed to the server.
2767314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber            mUriHeaders.removeItemsAt(index);
2777314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
278a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(INCOGNITO, SET);
2797314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber        }
2807314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber    }
2817314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber
2827314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber    if (!(mFlags & INCOGNITO)) {
283df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("setDataSource_l('%s')", mUri.string());
2847314fa17093d514199fedcb55ac41136a1b31cb3Andreas Huber    } else {
285df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("setDataSource_l(URL suppressed)");
28666b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
28766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
288bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    // The actual work will be done during preparation in the call to
289bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    // ::finishSetDataSource_l to avoid blocking the calling thread in
290bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    // setDataSource for any significant time.
29166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
292a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
293a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
294a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFd = -1;
295a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mURI = mUri;
296a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
297a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
298bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    return OK;
299bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
300bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
301bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::setDataSource(
302bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        int fd, int64_t offset, int64_t length) {
303bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
304bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
305bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    reset_l();
306bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
3077b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    sp<DataSource> dataSource = new FileSource(fd, offset, length);
308bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
3097b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    status_t err = dataSource->initCheck();
310bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
311bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (err != OK) {
312bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return err;
313bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
314bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
3157b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mFileSource = dataSource;
3167b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
317a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
318a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
319a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFd = fd;
320a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mURI = String8();
321a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
322a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
3237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    return setDataSource_l(dataSource);
3247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber}
3257b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
326e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstatus_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
32785704836f33a199d7e442a23db82abbd5620d35dAndreas Huber    return INVALID_OPERATION;
328e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
329e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
3307b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huberstatus_t AwesomePlayer::setDataSource_l(
3317b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        const sp<DataSource> &dataSource) {
3327b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
333bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
334bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (extractor == NULL) {
335bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return UNKNOWN_ERROR;
336bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
337bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
338785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
339785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong    if (mDecryptHandle != NULL) {
340785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong        CHECK(mDrmManagerClient);
341785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
342785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
3438f64134f749e4f7861a08a3063450fc714c4651dGloria Wang        }
344dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
345dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
346bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return setDataSource_l(extractor);
347bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
348bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
349bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
3507fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    // Attempt to approximate overall stream bitrate by summing all
3517fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    // tracks' individual bitrates, if not all of them advertise bitrate,
3527fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    // we have to fail.
3537fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3547fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    int64_t totalBitRate = 0;
3557fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3567fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
3577fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
3587fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3597fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        int32_t bitrate;
3607fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
361a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            const char *mime;
362a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            CHECK(meta->findCString(kKeyMIMEType, &mime));
3633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("track of type '%s' does not publish bitrate", mime);
364a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
3657fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            totalBitRate = -1;
3667fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            break;
3677fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        }
3687fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3697fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        totalBitRate += bitrate;
3707fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    }
3717fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3727fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    mBitrate = totalBitRate;
3737fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
3743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("mBitrate = %lld bits/sec", mBitrate);
3757fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
376a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
377a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
378a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mBitrate = mBitrate;
379a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mTracks.clear();
380a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mAudioTrackIndex = -1;
381a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoTrackIndex = -1;
382a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
383a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
384bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    bool haveAudio = false;
385bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    bool haveVideo = false;
386bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
387bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
388bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
38932bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber        const char *_mime;
39032bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &_mime));
391bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
39232bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber        String8 mime = String8(_mime);
39332bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber
39432bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber        if (!haveVideo && !strncasecmp(mime.string(), "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);
41532bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber                stat->mMIME = mime.string();
416a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            }
41732bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber        } else if (!haveAudio && !strncasecmp(mime.string(), "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);
42732bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber                stat->mMIME = mime.string();
428a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            }
429a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
43032bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber            if (!strcasecmp(mime.string(), 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            }
44232bdfd5acb76a02e82e0059c8bd892bc1f73a7e3Andreas Huber        } else if (!strcasecmp(mime.string(), 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) {
486df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("interrupting the connection process");
487e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            mConnectingDataSource->disconnect();
488e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        }
4896a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber
4906a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber        if (mFlags & PREPARING_CONNECTED) {
4916a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber            // We are basically done preparing, we're just buffering
4926a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber            // enough data to start playback, we can safely interrupt that.
4936a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber            finishAsyncPrepare_l();
4946a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber        }
495e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    }
496e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
497bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    while (mFlags & PREPARING) {
498bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        mPreparedCondition.wait(mLock);
499bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
500bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
501bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    cancelPlayerEvents();
502bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
503681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    mWVMExtractor.clear();
5040a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    mCachedSource.clear();
50588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mAudioTrack.clear();
50688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mVideoTrack.clear();
50788d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
5087b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // Shutdown audio first, so that the respone to the reset request
5097b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // appears to happen instantaneously as far as the user is concerned
5107b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // If we did this later, audio would continue playing while we
5117b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // shutdown the video-related resources and the player appear to
5127b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    // not be as responsive to a reset request.
5135b75fdc8fbc026453888cbb2d3fe31345394618bGloria Wang    if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
5145b75fdc8fbc026453888cbb2d3fe31345394618bGloria Wang            && mAudioSource != NULL) {
515e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        // If we had an audio player, it would have effectively
516e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        // taken possession of the audio source and stopped it when
517e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        // _it_ is stopped. Otherwise this is still our responsibility.
518e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mAudioSource->stop();
519e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    }
5207b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mAudioSource.clear();
5217b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5227b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mTimeSource = NULL;
5237b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5247b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    delete mAudioPlayer;
5257b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mAudioPlayer = NULL;
5267b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextPlayer != NULL) {
5287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        delete mTextPlayer;
5297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer = NULL;
5307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
5317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
532b9280d5c2313c41eb490f58198c4e59118e0e3e6Andreas Huber    mVideoRenderer.clear();
533b9280d5c2313c41eb490f58198c4e59118e0e3e6Andreas Huber
534bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoSource != NULL) {
535150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        shutdownVideoDecoder_l();
536bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
537bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
538bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mDurationUs = -1;
539a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(0, ASSIGN);
540acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    mExtractorFlags = 0;
541bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mTimeSourceDeltaUs = 0;
542bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoTimeUs = 0;
543bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
54464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    mSeeking = NO_SEEK;
545af64a8a6ad89f52685e822dca30742a4132c9ae6Gloria Wang    mSeekNotificationSent = true;
546bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mSeekTimeUs = 0;
54766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
548bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mUri.setTo("");
549bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mUriHeaders.clear();
5507b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5517b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    mFileSource.clear();
5527b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber
5537fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    mBitrate = -1;
554150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mLastVideoTimeUs = -1;
555a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
556a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
557a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
558a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFd = -1;
559a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mURI = String8();
560a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mBitrate = -1;
561a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mAudioTrackIndex = -1;
562a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoTrackIndex = -1;
563a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mNumVideoFramesDecoded = 0;
564a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mNumVideoFramesDropped = 0;
565a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoWidth = -1;
566a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoHeight = -1;
567a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFlags = 0;
568a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mTracks.clear();
569a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
570a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
57199590d29c9d3081cadfccd036842f5ce9a7debefAndreas Huber    mWatchForAudioSeekComplete = false;
57299590d29c9d3081cadfccd036842f5ce9a7debefAndreas Huber    mWatchForAudioEOS = false;
573bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
574bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
575c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Hubervoid AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
5760726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber    if (mListener != NULL) {
5770726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber        sp<MediaPlayerBase> listener = mListener.promote();
5780726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber
5790726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber        if (listener != NULL) {
580c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            listener->sendEvent(msg, ext1, ext2);
58166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        }
58266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
58366b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber}
58466b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
5857fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huberbool AwesomePlayer::getBitrate(int64_t *bitrate) {
586c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t size;
5877fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    if (mDurationUs >= 0 && mCachedSource != NULL
5887fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            && mCachedSource->getSize(&size) == OK) {
5897fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
5907fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        return true;
5917fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    }
5927fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
5937fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    if (mBitrate >= 0) {
5947fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        *bitrate = mBitrate;
5957fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber        return true;
5967fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    }
5977fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
5987fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    *bitrate = 0;
5997fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
6007fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    return false;
6017fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber}
6027fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber
6038650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber// Returns true iff cached duration is available/applicable.
6048650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huberbool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
6057fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber    int64_t bitrate;
6068650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
6072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mCachedSource != NULL && getBitrate(&bitrate)) {
6081bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        status_t finalStatus;
6091bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
6108650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
6111bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        *eos = (finalStatus != OK);
6128650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        return true;
613681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    } else if (mWVMExtractor != NULL) {
614681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        status_t finalStatus;
615681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        *durationUs = mWVMExtractor->getCachedDurationUs(&finalStatus);
616681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        *eos = (finalStatus != OK);
617681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        return true;
6188650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
6198650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
6208650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    return false;
6218650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber}
6228650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
62334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Hubervoid AwesomePlayer::ensureCacheIsFetching_l() {
62434ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber    if (mCachedSource != NULL) {
62534ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber        mCachedSource->resumeFetchingIfNecessary();
62634ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber    }
62734ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber}
62834ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber
629145e68fc778275963189b02a1adcbe27cce4d769Andreas Hubervoid AwesomePlayer::onVideoLagUpdate() {
630145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    Mutex::Autolock autoLock(mLock);
631145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    if (!mVideoLagEventPending) {
632145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        return;
633145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    }
634145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEventPending = false;
635145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
636145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
637145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
638145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
6395dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
6403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("video late by %lld ms.", videoLateByUs / 1000ll);
641145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
642145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        notifyListener_l(
643145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber                MEDIA_INFO,
644145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber                MEDIA_INFO_VIDEO_TRACK_LAGGING,
645145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber                videoLateByUs / 1000ll);
646145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    }
647145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
648145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    postVideoLagEvent_l();
649145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber}
650145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
65166b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Hubervoid AwesomePlayer::onBufferingUpdate() {
65266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    Mutex::Autolock autoLock(mLock);
653d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    if (!mBufferingEventPending) {
654d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber        return;
655d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    }
65666b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mBufferingEventPending = false;
65766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
6588650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mCachedSource != NULL) {
6591bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        status_t finalStatus;
6601bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
6611bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney        bool eos = (finalStatus != OK);
662c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
6638650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (eos) {
6641bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney            if (finalStatus == ERROR_END_OF_STREAM) {
6651bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
6661bd233ce7e1aa7730bc18d46ffd57791391738cdBryan Mawhinney            }
66783977eb230d829cfe520f55d7977037a904ce548Andreas Huber            if (mFlags & PREPARING) {
6683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("cache has reached EOS, prepare is done.");
66983977eb230d829cfe520f55d7977037a904ce548Andreas Huber                finishAsyncPrepare_l();
67083977eb230d829cfe520f55d7977037a904ce548Andreas Huber            }
6718650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        } else {
6727fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            int64_t bitrate;
6737fbdb0903dfbf70b314a74e64e28fb880cdb9247Andreas Huber            if (getBitrate(&bitrate)) {
6748650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                size_t cachedSize = mCachedSource->cachedSize();
6758650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
676c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
6778650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
6788650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                if (percentage > 100) {
6798650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    percentage = 100;
6808650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                }
681c9e894872c298b25fe9d74e68aa1e7287a541ac3Andreas Huber
6828650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
6838650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            } else {
6848650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                // We don't know the bitrate of the stream, use absolute size
6858650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                // limits to maintain the cache.
6868650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber
6878650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                if ((mFlags & PLAYING) && !eos
6888650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
689df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                    ALOGI("cache is running low (< %d) , pausing.",
6908650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                         kLowWaterMarkBytes);
691a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    modifyFlags(CACHE_UNDERRUN, SET);
6928650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    pause_l();
69334ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber                    ensureCacheIsFetching_l();
6945b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                    sendCacheStats();
6958650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
6968650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
6978650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    if (mFlags & CACHE_UNDERRUN) {
698df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                        ALOGI("cache has filled up (> %d), resuming.",
6998650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                             kHighWaterMarkBytes);
700a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                        modifyFlags(CACHE_UNDERRUN, CLEAR);
7018650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        play_l();
7028650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
7038650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    } else if (mFlags & PREPARING) {
7043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                        ALOGV("cache has filled up (> %d), prepare is done",
7058650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                             kHighWaterMarkBytes);
7068650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                        finishAsyncPrepare_l();
7078650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                    }
7088650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                }
7098650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            }
7108650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        }
711681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    } else if (mWVMExtractor != NULL) {
712681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        status_t finalStatus;
713681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
714681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        int64_t cachedDurationUs
715681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            = mWVMExtractor->getCachedDurationUs(&finalStatus);
716681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
717681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        bool eos = (finalStatus != OK);
718681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
719681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (eos) {
720681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            if (finalStatus == ERROR_END_OF_STREAM) {
721681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
722681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            }
723681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            if (mFlags & PREPARING) {
7243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("cache has reached EOS, prepare is done.");
725681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                finishAsyncPrepare_l();
726681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            }
727681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        } else {
728681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
729681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            if (percentage > 100) {
730681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                percentage = 100;
731681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            }
732681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
733681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
734681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
7352415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    }
7362415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber
7378650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    int64_t cachedDurationUs;
7382a4b49bd3863024884a694b454e2e452752e6ea0Andreas Huber    bool eos;
7398650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
7403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("cachedDurationUs = %.2f secs, eos=%d",
74134ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber             cachedDurationUs / 1E6, eos);
74234ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber
7438650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if ((mFlags & PLAYING) && !eos
7448650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                && (cachedDurationUs < kLowWaterMarkUs)) {
745df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("cache is running low (%.2f secs) , pausing.",
7468650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                 cachedDurationUs / 1E6);
747a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(CACHE_UNDERRUN, SET);
7488650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            pause_l();
74934ef0f32c8fc0186236a27e07405328cc1f7c56dAndreas Huber            ensureCacheIsFetching_l();
7505b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            sendCacheStats();
7518650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
7522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
7538650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            if (mFlags & CACHE_UNDERRUN) {
754df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("cache has filled up (%.2f secs), resuming.",
7558650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                     cachedDurationUs / 1E6);
756a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(CACHE_UNDERRUN, CLEAR);
7578650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                play_l();
7588650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
7598650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            } else if (mFlags & PREPARING) {
7603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("cache has filled up (%.2f secs), prepare is done",
7618650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                     cachedDurationUs / 1E6);
7628650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber                finishAsyncPrepare_l();
7632a4b49bd3863024884a694b454e2e452752e6ea0Andreas Huber            }
7642a4b49bd3863024884a694b454e2e452752e6ea0Andreas Huber        }
7650a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    }
7660a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
7670a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    postBufferingEvent_l();
7680726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber}
7690726045216f576e97672ebeefc265d39c4ebaaa5Andreas Huber
7705b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongvoid AwesomePlayer::sendCacheStats() {
7715b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    sp<MediaPlayerBase> listener = mListener.promote();
772b33d2ac90cfce0fe6db8c3e979e7ae2bbfc28163James Dong    if (listener != NULL && mCachedSource != NULL) {
7735b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        int32_t kbps = 0;
7745b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        status_t err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
7755b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        if (err == OK) {
7765b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            listener->sendEvent(
7775b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong                MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
7785b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        }
7795b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
7805b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
7815b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
782bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::onStreamDone() {
783bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    // Posted whenever any stream finishes playing.
784bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
785bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
786d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    if (!mStreamDoneEventPending) {
787d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber        return;
788d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    }
789bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = false;
790bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
791ed8d14f6a934072cd012992c4ef16990a54baa9aAndreas Huber    if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
7923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("MEDIA_ERROR %d", mStreamDoneStatus);
7935d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
7945d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        notifyListener_l(
7955d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
7965d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
797b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        pause_l(true /* at eos */);
7985d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
799a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AT_EOS, SET);
8005d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        return;
8015d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    }
8025d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
8035d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    const bool allDone =
8045d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
8055d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber            && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
8065d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
8075d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    if (!allDone) {
8085d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        return;
8095d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    }
8105d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
811cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber    if ((mFlags & LOOPING)
812cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber            || ((mFlags & AUTO_LOOPING)
813cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber                && (mAudioSink == NULL || mAudioSink->realtime()))) {
814cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber        // Don't AUTO_LOOP if we're being recorded, since that cannot be
815cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber        // turned off and recording would go on indefinitely.
816cdef698dae0c6dd89755f6494cc3d4b163f410efAndreas Huber
817bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        seekTo_l(0);
818bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
819a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        if (mVideoSource != NULL) {
820bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            postVideoEvent_l();
821bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
822bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    } else {
8233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("MEDIA_PLAYBACK_COMPLETE");
8245d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
825bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
826b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        pause_l(true /* at eos */);
8272e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
828a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AT_EOS, SET);
829bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
830bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
831bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
832bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::play() {
833bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
8340a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
835a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(CACHE_UNDERRUN, CLEAR);
8360a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
8377b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    return play_l();
8387b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber}
839bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
8407b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huberstatus_t AwesomePlayer::play_l() {
841a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(SEEK_PREVIEW, CLEAR);
8422b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
843bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mFlags & PLAYING) {
844bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return OK;
845bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
846bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
847bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (!(mFlags & PREPARED)) {
848bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        status_t err = prepare_l();
849bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
850bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        if (err != OK) {
851bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber            return err;
852bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        }
853bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
854bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
855a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PLAYING, SET);
856a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(FIRST_FRAME, SET);
857bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
858c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang    if (mDecryptHandle != NULL) {
859c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang        int64_t position;
860c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang        getPosition(&position);
861c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
862c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang                Playback::START, position / 1000);
863c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang    }
864c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang
865bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mAudioSource != NULL) {
866bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        if (mAudioPlayer == NULL) {
867bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (mAudioSink != NULL) {
868ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber                mAudioPlayer = new AudioPlayer(mAudioSink, this);
869bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                mAudioPlayer->setSource(mAudioSource);
870e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber
871f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                mTimeSource = mAudioPlayer;
87288c030e0e0152791ff74f90249f55fce01371198Andreas Huber
873b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // If there was a seek request before we ever started,
874b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // honor the request now.
875b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // Make sure to do this before starting the audio player
876b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                // to avoid a race condition.
877b874cd085bba63528c570f74c493bfea835190d9Andreas Huber                seekAudioIfNecessary_l();
878f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            }
879f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        }
88088c030e0e0152791ff74f90249f55fce01371198Andreas Huber
881f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        CHECK(!(mFlags & AUDIO_RUNNING));
882c130b5bf563d049bd391ccd96985ac278ef8ff8dGloria Wang
883f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        if (mVideoSource == NULL) {
8845442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            // We don't want to post an error notification at this point,
8855442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            // the error returned from MediaPlayer::start() will suffice.
8865442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber
8875442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            status_t err = startAudioPlayer_l(
8885442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber                    false /* sendErrorNotification */);
889bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
890f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            if (err != OK) {
891f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                delete mAudioPlayer;
892f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                mAudioPlayer = NULL;
893bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
894a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags((PLAYING | FIRST_FRAME), CLEAR);
8951862a33b246249630b654182afb5914da3480d4cAndreas Huber
896f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                if (mDecryptHandle != NULL) {
897f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                    mDrmManagerClient->setPlaybackStatus(
898f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                            mDecryptHandle, Playback::STOP, 0);
899f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                }
900f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
901f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                return err;
902bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
903bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
904bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
905bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
906bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mTimeSource == NULL && mAudioPlayer == NULL) {
9075d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        mTimeSource = &mSystemTimeSource;
908bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
909bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
910bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoSource != NULL) {
911a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        // Kick off video playback
912a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        postVideoEvent_l();
913145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
914145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        if (mAudioSource != NULL && mVideoSource != NULL) {
915145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber            postVideoLagEvent_l();
916145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        }
917bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
918bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
9192e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    if (mFlags & AT_EOS) {
9202e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        // Legacy behaviour, if a stream finishes playing and then
9212e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        // is started again, we play from the start...
9222e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        seekTo_l(0);
9232e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    }
9242e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
9257cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
9267cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        | IMediaPlayerService::kBatteryDataTrackDecoder;
9277cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
9287cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackAudio;
9297cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
9307cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (mVideoSource != NULL) {
9317cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackVideo;
9327cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
9337cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    addBatteryData(params);
9347cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
935bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
936bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
937bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
9385442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huberstatus_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
939f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    CHECK(!(mFlags & AUDIO_RUNNING));
940f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
941f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (mAudioSource == NULL || mAudioPlayer == NULL) {
942f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        return OK;
943f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    }
944f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
945f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (!(mFlags & AUDIOPLAYER_STARTED)) {
946a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AUDIOPLAYER_STARTED, SET);
947f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
948c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        bool wasSeeking = mAudioPlayer->isSeeking();
949c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
950f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        // We've already started the MediaSource in order to enable
951f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        // the prefetcher to read its data.
952f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        status_t err = mAudioPlayer->start(
953f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber                true /* sourceAlreadyStarted */);
954f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
955f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        if (err != OK) {
9565442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            if (sendErrorNotification) {
9575442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber                notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
9585442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber            }
9595442cb59e8483e18b3a02400d431d167ea7074b3Andreas Huber
960f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            return err;
961f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        }
962c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
963c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        if (wasSeeking) {
964c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber            CHECK(!mAudioPlayer->isSeeking());
965c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber
966c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber            // We will have finished the seek while starting the audio player.
96702f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            postAudioSeekComplete();
968c0dfc5b02d4179769bbdd25c10d430576ec09568Andreas Huber        }
969f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    } else {
970f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        mAudioPlayer->resume();
971f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    }
972f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
973a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(AUDIO_RUNNING, SET);
974f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
975f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    mWatchForAudioEOS = true;
976f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
977f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    return OK;
978f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber}
979f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
9805daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Hubervoid AwesomePlayer::notifyVideoSize_l() {
9815daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    sp<MetaData> meta = mVideoSource->getFormat();
9825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
983f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t cropLeft, cropTop, cropRight, cropBottom;
984f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findRect(
985f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
986f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        int32_t width, height;
987f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        CHECK(meta->findInt32(kKeyWidth, &width));
988f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        CHECK(meta->findInt32(kKeyHeight, &height));
989f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
990f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        cropLeft = cropTop = 0;
991f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        cropRight = width - 1;
992f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        cropBottom = height - 1;
993f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
9943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("got dimensions only %d x %d", width, height);
995f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    } else {
9963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("got crop rect %d, %d, %d, %d",
997f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber             cropLeft, cropTop, cropRight, cropBottom);
998f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
999f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
10009cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    int32_t displayWidth;
10019cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
10023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
10039cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong        mDisplayWidth = displayWidth;
10049cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    }
10059cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    int32_t displayHeight;
10069cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
10073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
10089cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong        mDisplayHeight = displayHeight;
10099cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong    }
10109cbb1a6f99003a9cd8765e11b9d7380e67839f82James Dong
1011f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t usableWidth = cropRight - cropLeft + 1;
1012f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t usableHeight = cropBottom - cropTop + 1;
1013b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    if (mDisplayWidth != 0) {
1014b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong        usableWidth = mDisplayWidth;
1015b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    }
1016b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    if (mDisplayHeight != 0) {
1017b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong        usableHeight = mDisplayHeight;
1018b45c01c2b8588ff431b511151666a55a39f0a6aeJames Dong    }
10195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1020a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
1021a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
1022a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoWidth = usableWidth;
1023a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mVideoHeight = usableHeight;
1024a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
1025a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1026ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t rotationDegrees;
1027ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (!mVideoTrack->getFormat()->findInt32(
1028ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                kKeyRotation, &rotationDegrees)) {
1029ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
1030ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1031ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
1032ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (rotationDegrees == 90 || rotationDegrees == 270) {
1033ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        notifyListener_l(
1034f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
1035ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    } else {
1036ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        notifyListener_l(
1037f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
1038ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
10395daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
10405daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1041bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::initRenderer_l() {
10421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (mNativeWindow == NULL) {
10430a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        return;
10440a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    }
1045bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
10460a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    sp<MetaData> meta = mVideoSource->getFormat();
1047bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
10480a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    int32_t format;
10490a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    const char *component;
10500a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    int32_t decodedWidth, decodedHeight;
10510a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &format));
10520a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findCString(kKeyDecoderComponent, &component));
10530a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
10540a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
10554844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber
1056ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    int32_t rotationDegrees;
1057ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (!mVideoTrack->getFormat()->findInt32(
1058ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                kKeyRotation, &rotationDegrees)) {
1059ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        rotationDegrees = 0;
1060ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
1061ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
10620a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    mVideoRenderer.clear();
10634844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber
10640a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    // Must ensure that mVideoRenderer's destructor is actually executed
10650a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    // before creating a new one.
10660a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    IPCThreadState::self()->flushCommands();
10670a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber
1068bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (USE_SURFACE_ALLOC
1069bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            && !strncmp(component, "OMX.", 4)
10702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            && strncmp(component, "OMX.google.", 11)
10712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            && strcmp(component, "OMX.Nvidia.mpeg2v.decode")) {
10720a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // Hardware decoders avoid the CPU color conversion by decoding
10730a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // directly to ANativeBuffers, so we must use a renderer that
10740a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // just pushes those buffers to the ANativeWindow.
1075ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        mVideoRenderer =
10761173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
10770a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber    } else {
10780a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // Other decoders are instantiated locally and as a consequence
10790a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // allocate their buffers in local address space.  This renderer
10800a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // then performs a color conversion and copy to get the data
10810a5ca668c6f7d45706e9aec4a1dfec0aacc6d233Andreas Huber        // into the ANativeBuffer.
10821173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
1083bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1084bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1085bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1086bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::pause() {
1087bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
10880a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1089a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(CACHE_UNDERRUN, CLEAR);
10900a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1091bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return pause_l();
1092bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1093bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1094b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huberstatus_t AwesomePlayer::pause_l(bool at_eos) {
1095bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (!(mFlags & PLAYING)) {
1096bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return OK;
1097bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1098bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1099c34233e673c9791e137456d0c427d58db184b690Andreas Huber    cancelPlayerEvents(true /* keepNotifications */);
1100bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1101f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1102b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        if (at_eos) {
1103b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            // If we played the audio stream to completion we
1104b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            // want to make sure that all samples remaining in the audio
1105b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            // track's queue are played out.
1106b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioPlayer->pause(true /* playPendingSamples */);
1107b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        } else {
1108b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber            mAudioPlayer->pause();
1109b2e3954c94717e43b3dc9b880564f166cfbbc0a2Andreas Huber        }
1110f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
1111a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AUDIO_RUNNING, CLEAR);
1112bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1113bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
11147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mFlags & TEXTPLAYER_STARTED) {
11157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer->pause();
1116a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(TEXT_RUNNING, CLEAR);
11177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
11187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1119a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PLAYING, CLEAR);
1120bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1121dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    if (mDecryptHandle != NULL) {
1122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1123dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                Playback::PAUSE, 0);
1124dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
1125dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
11267cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
11277cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
11287cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackAudio;
11297cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
11307cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (mVideoSource != NULL) {
11317cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        params |= IMediaPlayerService::kBatteryDataTrackVideo;
11327cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
11337cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
11347cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    addBatteryData(params);
11357cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
1136bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1137bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1138bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1139bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberbool AwesomePlayer::isPlaying() const {
11400a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
1141bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1142bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
114363970b42f101c87db7cfd26d43b0d300260b1582Andreas Huberstatus_t AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
11441173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    Mutex::Autolock autoLock(mLock);
11451173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
114663970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    status_t err;
11471173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (surfaceTexture != NULL) {
114863970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        err = setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
114980ec929862bcfe8582984f3a28e7a4ca5f4f27bbGloria Wang    } else {
115063970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        err = setNativeWindow_l(NULL);
11511173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    }
115263970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
115363970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    return err;
1154150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber}
11551173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
1156150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Hubervoid AwesomePlayer::shutdownVideoDecoder_l() {
1157150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (mVideoBuffer) {
1158150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mVideoBuffer->release();
1159150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mVideoBuffer = NULL;
1160150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1161150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1162150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mVideoSource->stop();
1163150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1164150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    // The following hack is necessary to ensure that the OMX
1165150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    // component is completely released by the time we may try
1166150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    // to instantiate it again.
1167150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    wp<MediaSource> tmp = mVideoSource;
1168150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mVideoSource.clear();
1169150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    while (tmp.promote() != NULL) {
1170150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        usleep(1000);
1171150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1172150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    IPCThreadState::self()->flushCommands();
11733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("video decoder shutdown completed");
1174150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber}
1175150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
117663970b42f101c87db7cfd26d43b0d300260b1582Andreas Huberstatus_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
1177150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mNativeWindow = native;
1178150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1179150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (mVideoSource == NULL) {
118063970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        return OK;
1181150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1182150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
11833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("attempting to reconfigure to use new surface");
1184150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1185150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    bool wasPlaying = (mFlags & PLAYING) != 0;
1186150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1187150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    pause_l();
1188150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mVideoRenderer.clear();
1189150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1190150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    shutdownVideoDecoder_l();
1191150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
119263970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    status_t err = initVideoDecoder();
119363970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
119463970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    if (err != OK) {
119529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("failed to reinstantiate video decoder after surface change.");
119663970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber        return err;
119763970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    }
1198150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1199150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (mLastVideoTimeUs >= 0) {
1200150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mSeeking = SEEK;
1201150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        mSeekTimeUs = mLastVideoTimeUs;
1202a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
1203150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
1204150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
1205150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    if (wasPlaying) {
1206150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber        play_l();
1207150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    }
120863970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber
120963970b42f101c87db7cfd26d43b0d300260b1582Andreas Huber    return OK;
12105daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
12115daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1212bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::setAudioSink(
1213bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        const sp<MediaPlayerBase::AudioSink> &audioSink) {
1214bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
1215bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1216bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mAudioSink = audioSink;
1217bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1218bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1219bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::setLooping(bool shouldLoop) {
1220bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
1221bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1222a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(LOOPING, CLEAR);
1223bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1224bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (shouldLoop) {
1225a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(LOOPING, SET);
1226bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1227bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1228bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1229bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1230bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1231bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::getDuration(int64_t *durationUs) {
12322415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    Mutex::Autolock autoLock(mMiscStateLock);
1233bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1234bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mDurationUs < 0) {
1235bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return UNKNOWN_ERROR;
1236bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1237bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1238bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    *durationUs = mDurationUs;
1239bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1240bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1241bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1242bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1243bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::getPosition(int64_t *positionUs) {
12442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mSeeking != NO_SEEK) {
1245dac4ee72bac87388a1495e098f39d73168c8078fAndreas Huber        *positionUs = mSeekTimeUs;
12465dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    } else if (mVideoSource != NULL
12475dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber            && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
12482415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber        Mutex::Autolock autoLock(mMiscStateLock);
1249bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        *positionUs = mVideoTimeUs;
1250bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    } else if (mAudioPlayer != NULL) {
1251bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        *positionUs = mAudioPlayer->getMediaTimeUs();
1252bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    } else {
1253bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        *positionUs = 0;
1254bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1255bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1256bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1257bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1258bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1259bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::seekTo(int64_t timeUs) {
126070f521de2675ce6eedf4b22beed94ea1289b0f38Andreas Huber    if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
1261acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber        Mutex::Autolock autoLock(mLock);
1262acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber        return seekTo_l(timeUs);
1263acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    }
1264acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
1265acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    return OK;
1266bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1267bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
12687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
12697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextPlayer != NULL) {
12707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        if (index >= 0) { // to turn on a text track
12717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            status_t err = mTextPlayer->setTimedTextTrackIndex(index);
12727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (err != OK) {
12737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                return err;
12747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
12757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1276a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(TEXT_RUNNING, SET);
1277a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(TEXTPLAYER_STARTED, SET);
12787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            return OK;
12797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        } else { // to turn off the text track display
12807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mFlags  & TEXT_RUNNING) {
1281a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(TEXT_RUNNING, CLEAR);
12827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
12837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (mFlags  & TEXTPLAYER_STARTED) {
1284a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(TEXTPLAYER_STARTED, CLEAR);
12857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
12867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
12877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            return mTextPlayer->setTimedTextTrackIndex(index);
12887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
12897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    } else {
12907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return INVALID_OPERATION;
12917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
12927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
12937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1294bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberstatus_t AwesomePlayer::seekTo_l(int64_t timeUs) {
12950a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    if (mFlags & CACHE_UNDERRUN) {
1296a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(CACHE_UNDERRUN, CLEAR);
12970a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber        play_l();
12980a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber    }
12990a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
13005dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
13015dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        // Video playback completed before, there's no pending
13025dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        // video event right now. In order for this new seek
13035dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        // to be honored, we need to post one.
13045dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber
13055dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        postVideoEvent_l();
13065dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber    }
13075dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber
130864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    mSeeking = SEEK;
13091321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber    mSeekNotificationSent = false;
1310bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mSeekTimeUs = timeUs;
1311a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
1312bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1313bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    seekAudioIfNecessary_l();
1314bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
13157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mFlags & TEXTPLAYER_STARTED) {
13167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer->seekTo(mSeekTimeUs);
13177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
13187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13191321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber    if (!(mFlags & PLAYING)) {
13203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("seeking while paused, sending SEEK_COMPLETE notification"
13211321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber             " immediately.");
13221321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber
13231321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        notifyListener_l(MEDIA_SEEK_COMPLETE);
13241321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        mSeekNotificationSent = true;
13252b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
13262b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        if ((mFlags & PREPARED) && mVideoSource != NULL) {
1327a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            modifyFlags(SEEK_PREVIEW, SET);
13282b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            postVideoEvent_l();
13292b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        }
13301321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber    }
13311321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber
1332bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return OK;
1333bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1334bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1335bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::seekAudioIfNecessary_l() {
133664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
1337bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        mAudioPlayer->seekTo(mSeekTimeUs);
1338bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
13391862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioSeekComplete = true;
13401862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioEOS = true;
1341dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
1342dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        if (mDecryptHandle != NULL) {
1343dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1344dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    Playback::PAUSE, 0);
1345dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1346dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang                    Playback::START, mSeekTimeUs / 1000);
1347dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang        }
1348bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1349bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1350bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
135188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Hubervoid AwesomePlayer::setAudioSource(sp<MediaSource> source) {
135288d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    CHECK(source != NULL);
1353bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
135488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mAudioTrack = source;
135588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber}
135688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
13577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid AwesomePlayer::addTextSource(sp<MediaSource> source) {
1358965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    Mutex::Autolock autoLock(mTimedTextLock);
13597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(source != NULL);
13607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextPlayer == NULL) {
13627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
13637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
13647a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
13657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextPlayer->addTextSource(source);
13667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
13677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
136888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huberstatus_t AwesomePlayer::initAudioDecoder() {
136988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    sp<MetaData> meta = mAudioTrack->getFormat();
1370717826ececd8d39596f62418677721d70776add1Andreas Huber
1371717826ececd8d39596f62418677721d70776add1Andreas Huber    const char *mime;
1372717826ececd8d39596f62418677721d70776add1Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
1373717826ececd8d39596f62418677721d70776add1Andreas Huber
1374717826ececd8d39596f62418677721d70776add1Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
137588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        mAudioSource = mAudioTrack;
1376717826ececd8d39596f62418677721d70776add1Andreas Huber    } else {
1377717826ececd8d39596f62418677721d70776add1Andreas Huber        mAudioSource = OMXCodec::Create(
137888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber                mClient.interface(), mAudioTrack->getFormat(),
1379717826ececd8d39596f62418677721d70776add1Andreas Huber                false, // createEncoder
138088d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber                mAudioTrack);
1381717826ececd8d39596f62418677721d70776add1Andreas Huber    }
1382bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1383bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mAudioSource != NULL) {
1384bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        int64_t durationUs;
138588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
13862415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber            Mutex::Autolock autoLock(mMiscStateLock);
1387bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (mDurationUs < 0 || durationUs > mDurationUs) {
1388bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                mDurationUs = durationUs;
1389bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
1390bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1391bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1392a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber        status_t err = mAudioSource->start();
1393a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber
1394a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber        if (err != OK) {
1395a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber            mAudioSource.clear();
1396a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber            return err;
1397a945bfd91aa291fba4d9201ffcb38fce40eab7feAndreas Huber        }
139881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
139981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // For legacy reasons we're simply going to ignore the absence
140081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // of an audio decoder for QCELP instead of aborting playback
140181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        // altogether.
140281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber        return OK;
140381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber    }
1404e7e3b785a0e7819db4c895a4f60e9a4dd755880cAndreas Huber
1405a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mAudioSource != NULL) {
1406a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
1407a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
1408a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1409a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        const char *component;
1410a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        if (!mAudioSource->getFormat()
1411a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                ->findCString(kKeyDecoderComponent, &component)) {
1412a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            component = "none";
1413a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
1414a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1415a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        stat->mDecoderName = component;
1416a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
1417a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1418bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
1419bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1420bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
142188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Hubervoid AwesomePlayer::setVideoSource(sp<MediaSource> source) {
142288d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    CHECK(source != NULL);
1423bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
142488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mVideoTrack = source;
142588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber}
142688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
14272a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huberstatus_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
14282eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten
14292eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // Either the application or the DRM system can independently say
14302eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // that there must be a hardware-protected path to an external video sink.
14312eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // For now we always require a hardware-protected path to external video sink
14322eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // if content is DRMed, but eventually this could be optional per DRM agent.
14332eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // When the application wants protection, then
14342eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    //   (USE_SURFACE_ALLOC && (mSurface != 0) &&
14352eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    //   (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
14362eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    // will be true, but that part is already handled by SurfaceFlinger.
1437eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten
1438eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#ifdef DEBUG_HDCP
1439eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // For debugging, we allow a system property to control the protected usage.
1440eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // In case of uninitialized or unexpected property, we default to "DRM only".
1441eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    bool setProtectionBit = false;
1442eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    char value[PROPERTY_VALUE_MAX];
1443eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    if (property_get("persist.sys.hdcp_checking", value, NULL)) {
1444eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        if (!strcmp(value, "never")) {
1445eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            // nop
1446eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        } else if (!strcmp(value, "always")) {
1447eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            setProtectionBit = true;
1448eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        } else if (!strcmp(value, "drm-only")) {
1449eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            if (mDecryptHandle != NULL) {
1450eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten                setProtectionBit = true;
1451eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            }
1452eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        // property value is empty, or unexpected value
1453eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        } else {
1454eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            if (mDecryptHandle != NULL) {
1455eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten                setProtectionBit = true;
1456eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            }
1457eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        }
1458eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // can' read property value
1459eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    } else {
1460eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        if (mDecryptHandle != NULL) {
1461eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten            setProtectionBit = true;
1462eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        }
1463eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    }
1464eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    // note that usage bit is already cleared, so no need to clear it in the "else" case
1465eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    if (setProtectionBit) {
1466eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten        flags |= OMXCodec::kEnableGrallocUsageProtected;
1467eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten    }
1468eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#else
14692eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    if (mDecryptHandle != NULL) {
14702eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten        flags |= OMXCodec::kEnableGrallocUsageProtected;
14712eb62955eb84b97695e8a7e56e14310cbb86412bGlenn Kasten    }
1472eabd34665adc284525fe7337ad5c56a8b92964efGlenn Kasten#endif
14733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("initVideoDecoder flags=0x%x", flags);
1474bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoSource = OMXCodec::Create(
147588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber            mClient.interface(), mVideoTrack->getFormat(),
1476bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            false, // createEncoder
147739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            mVideoTrack,
14781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
1479bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1480bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoSource != NULL) {
1481bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        int64_t durationUs;
148288d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
14832415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber            Mutex::Autolock autoLock(mMiscStateLock);
1484bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (mDurationUs < 0 || durationUs > mDurationUs) {
1485bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                mDurationUs = durationUs;
1486bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
1487bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1488bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1489139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        status_t err = mVideoSource->start();
1490139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber
1491139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        if (err != OK) {
1492139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber            mVideoSource.clear();
1493139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber            return err;
1494139a5d5bd33c9fc7708d0a79f11ee928f7796e6bAndreas Huber        }
1495bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1496bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1497a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mVideoSource != NULL) {
149814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        const char *componentName;
1499a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        CHECK(mVideoSource->getFormat()
150014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                ->findCString(kKeyDecoderComponent, &componentName));
1501a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
150214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        {
150314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            Mutex::Autolock autoLock(mStatsLock);
150414f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
150514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
150614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            stat->mDecoderName = componentName;
150714f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        }
150814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
150914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        static const char *kPrefix = "OMX.Nvidia.";
151014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        static const char *kSuffix = ".decode";
151114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        static const size_t kSuffixLength = strlen(kSuffix);
151214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
151314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        size_t componentNameLength = strlen(componentName);
151414f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
151514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        if (!strncmp(componentName, kPrefix, strlen(kPrefix))
151614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                && componentNameLength >= kSuffixLength
151714f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                && !strcmp(&componentName[
151814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    componentNameLength - kSuffixLength], kSuffix)) {
151914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            modifyFlags(SLOW_DECODER_HACK, SET);
152014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        }
1521a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
1522a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1523bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
1524bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1525bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
15264769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Hubervoid AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
152764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking == SEEK_VIDEO_ONLY) {
152864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        mSeeking = NO_SEEK;
152964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        return;
153064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    }
153164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
153264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
15334769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        return;
15344769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    }
15354769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
15364769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    if (mAudioPlayer != NULL) {
15373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
15384769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
15394769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // If we don't have a video time, seek audio to the originally
15404769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // requested seek time instead.
15414769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
15424769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
15434769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        mWatchForAudioSeekComplete = true;
15445dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber        mWatchForAudioEOS = true;
15454769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    } else if (!mSeekNotificationSent) {
15464769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // If we're playing video only, report seek complete now,
15474769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        // otherwise audio player will notify us later.
15484769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber        notifyListener_l(MEDIA_SEEK_COMPLETE);
1549512895089f2035bc86d3f502255199809aca721bAndreas Huber        mSeekNotificationSent = true;
15504769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    }
15514769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
1552a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(FIRST_FRAME, SET);
155364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    mSeeking = NO_SEEK;
1554a89082944308805b0def7de87c67e370e74b8789Gloria Wang
1555a89082944308805b0def7de87c67e370e74b8789Gloria Wang    if (mDecryptHandle != NULL) {
1556a89082944308805b0def7de87c67e370e74b8789Gloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1557a89082944308805b0def7de87c67e370e74b8789Gloria Wang                Playback::PAUSE, 0);
1558a89082944308805b0def7de87c67e370e74b8789Gloria Wang        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1559a89082944308805b0def7de87c67e370e74b8789Gloria Wang                Playback::START, videoTimeUs / 1000);
1560a89082944308805b0def7de87c67e370e74b8789Gloria Wang    }
15614769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber}
15624769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
1563c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Hubervoid AwesomePlayer::onVideoEvent() {
1564bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    Mutex::Autolock autoLock(mLock);
15657b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    if (!mVideoEventPending) {
15667b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        // The event has been cancelled in reset_l() but had already
15677b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        // been scheduled for execution at that time.
15687b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber        return;
15697b3396acc702451be9bafb19d7fe26d55d43a316Andreas Huber    }
1570bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = false;
1571bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
157264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking != NO_SEEK) {
1573bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        if (mVideoBuffer) {
1574bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            mVideoBuffer->release();
1575bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            mVideoBuffer = NULL;
1576bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
15770a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1578681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
15792b1222f8938356669672f35e0e53e176c78c40efAndreas Huber                && !(mFlags & SEEK_PREVIEW)) {
15800a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // We're going to seek the video source first, followed by
15810a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // the audio source.
15820a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // In order to avoid jumps in the DataSource offset caused by
15830a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // the audio codec prefetching data from the old locations
15840a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // while the video codec is already reading data from the new
15850a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // locations, we'll "pause" the audio source, causing it to
15860a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            // stop reading input data until a subsequent seek.
15870a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
1588f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
15890a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber                mAudioPlayer->pause();
1590f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
1591a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(AUDIO_RUNNING, CLEAR);
15920a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            }
15930a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber            mAudioSource->pause();
15940a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber        }
1595bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1596bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1597bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (!mVideoBuffer) {
1598bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        MediaSource::ReadOptions options;
159964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (mSeeking != NO_SEEK) {
16003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
1601bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1602abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            options.setSeekTo(
160364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                    mSeekTimeUs,
160464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                    mSeeking == SEEK_VIDEO_ONLY
160564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
160664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
1607bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1608bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        for (;;) {
1609bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            status_t err = mVideoSource->read(&mVideoBuffer, &options);
1610c1689e49ac867de33f2e81289449878ac2e536a0Andreas Huber            options.clearSeekTo();
1611bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1612bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            if (err != OK) {
1613e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                CHECK(mVideoBuffer == NULL);
1614bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1615bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                if (err == INFO_FORMAT_CHANGED) {
16163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("VideoSource signalled format change.");
1617bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
16185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    notifyVideoSize_l();
16195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1620a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber                    if (mVideoRenderer != NULL) {
1621fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber                        mVideoRendererIsPreview = false;
1622a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber                        initRenderer_l();
1623a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber                    }
1624bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                    continue;
1625bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                }
1626bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
16274769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                // So video playback is complete, but we may still have
16284769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                // a seek request pending that needs to be applied
16294769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                // to the audio track.
163064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                if (mSeeking != NO_SEEK) {
16313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("video stream ended while seeking!");
16324769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                }
16334769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber                finishSeekIfNecessary(-1);
16344769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber
16355dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                if (mAudioPlayer != NULL
16365dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                        && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
16375dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                    startAudioPlayer_l();
16385dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber                }
16395dac87b088556b8ed7f2a4f5546d31be0bb68680Andreas Huber
1640a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                modifyFlags(VIDEO_AT_EOS, SET);
16415295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber                postStreamDoneEvent_l(err);
1642bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber                return;
1643bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            }
1644bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
16454844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber            if (mVideoBuffer->range_length() == 0) {
164608411b75d4c30ce26180639f158e2f33d190eee8Andreas Huber                // Some decoders, notably the PV AVC software decoder
164708411b75d4c30ce26180639f158e2f33d190eee8Andreas Huber                // return spurious empty buffers that we just want to ignore.
164808411b75d4c30ce26180639f158e2f33d190eee8Andreas Huber
16494844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber                mVideoBuffer->release();
16504844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber                mVideoBuffer = NULL;
16514844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber                continue;
16524844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber            }
16534844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber
1654bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber            break;
1655bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        }
1656a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
1657a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        {
1658a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            Mutex::Autolock autoLock(mStatsLock);
1659a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            ++mStats.mNumVideoFramesDecoded;
1660a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
1661bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1662bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1663bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    int64_t timeUs;
1664bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1665bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1666150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber    mLastVideoTimeUs = timeUs;
1667150694cda0842d38a9358fe8d1fcb4fb4a76599eAndreas Huber
166864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (mSeeking == SEEK_VIDEO_ONLY) {
166964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (mSeekTimeUs > timeUs) {
1670df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
167164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                 mSeekTimeUs, timeUs);
167264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        }
167364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    }
167464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
16752415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    {
16762415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber        Mutex::Autolock autoLock(mMiscStateLock);
16772415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber        mVideoTimeUs = timeUs;
16782415ecb5bb4e1459024f6d6c8ae2d6e3dc4fbdc7Andreas Huber    }
1679bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
168064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    SeekType wasSeeking = mSeeking;
16814769cc92740e3ab58e9263d42553c12bbf79e3beAndreas Huber    finishSeekIfNecessary(timeUs);
1682bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1683f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1684f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        status_t err = startAudioPlayer_l();
1685f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        if (err != OK) {
168629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Starting the audio player failed w/ err %d", err);
1687f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber            return;
1688f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber        }
1689f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber    }
1690f03034408506051f2f836e59305fcd5f662bf19aAndreas Huber
16917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
16927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextPlayer->resume();
1693a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(TEXT_RUNNING, SET);
16947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
16957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1696f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber    TimeSource *ts =
1697f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber        ((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
1698f7eade99250520f2c9c8366a20a9256c4b34abc1Andreas Huber            ? &mSystemTimeSource : mTimeSource;
16995d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber
1700bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mFlags & FIRST_FRAME) {
1701a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(FIRST_FRAME, CLEAR);
170214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        mSinceLastDropped = 0;
17035d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber        mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
1704bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1705bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1706bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    int64_t realTimeUs, mediaTimeUs;
17075d2de4da54504836e4b772b3010ac28c19f667f0Andreas Huber    if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
1708bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
1709bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
1710bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1711bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
171264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (wasSeeking == SEEK_VIDEO_ONLY) {
171364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
171464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
171564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        int64_t latenessUs = nowUs - timeUs;
171664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
171764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (latenessUs > 0) {
1718df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
171964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        }
172064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    }
172164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
172264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (wasSeeking == NO_SEEK) {
172302a1db7dc1de2f2df306ec10bab992bc8bbaaca8Andreas Huber        // Let's display the first frame after seeking right away.
1724f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
17252b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1726bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
17272b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        int64_t latenessUs = nowUs - timeUs;
17282b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
172964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        if (latenessUs > 500000ll
173064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                && mAudioPlayer != NULL
173164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                && mAudioPlayer->getMediaTimeMapping(
173264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                    &realTimeUs, &mediaTimeUs)) {
1733df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("we're much too late (%.2f secs), video skipping ahead",
173464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber                 latenessUs / 1E6);
173564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
173664bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mVideoBuffer->release();
173764bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mVideoBuffer = NULL;
173864bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
173964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mSeeking = SEEK_VIDEO_ONLY;
174064bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            mSeekTimeUs = mediaTimeUs;
174164bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
174264bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            postVideoEvent_l();
174364bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber            return;
174464bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        }
174564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber
17462b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        if (latenessUs > 40000) {
17472b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            // We're more than 40ms late.
17483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("we're late by %lld us (%.2f secs)",
1749dab59b5a4956b7e9b1ffc64a0676e7990579934eAndreas Huber                 latenessUs, latenessUs / 1E6);
17502b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
175114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            if (!(mFlags & SLOW_DECODER_HACK)
175214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    || mSinceLastDropped > FRAME_DROP_FREQ)
1753a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            {
17543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("we're late by %lld us (%.2f secs) dropping "
175514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                     "one after %d frames",
175614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                     latenessUs, latenessUs / 1E6, mSinceLastDropped);
1757a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
175814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                mSinceLastDropped = 0;
175914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                mVideoBuffer->release();
176014f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                mVideoBuffer = NULL;
176114f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
176214f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                {
176314f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    Mutex::Autolock autoLock(mStatsLock);
176414f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                    ++mStats.mNumVideoFramesDropped;
176514f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                }
176614f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong
176714f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                postVideoEvent_l();
176814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong                return;
176914f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong            }
1770aee6c07b3572bf2510cd9e7d29c454fcfedde31dpmehendale        }
1771bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
17722b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        if (latenessUs < -10000) {
17732b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            // We're more than 10ms early.
1774bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
17752b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            postVideoEvent_l(10000);
17762b1222f8938356669672f35e0e53e176c78c40efAndreas Huber            return;
17772b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        }
1778bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1779bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
178080ec929862bcfe8582984f3a28e7a4ca5f4f27bbGloria Wang    if ((mNativeWindow != NULL)
178180ec929862bcfe8582984f3a28e7a4ca5f4f27bbGloria Wang            && (mVideoRendererIsPreview || mVideoRenderer == NULL)) {
1782fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber        mVideoRendererIsPreview = false;
1783fa090f541bb84a546af2ec834e91a032ff10e66eAndreas Huber
1784a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        initRenderer_l();
1785a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber    }
1786a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber
1787a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber    if (mVideoRenderer != NULL) {
178814f95746466fb6abdbbf33ee26d92ebf3fbef98fJames Dong        mSinceLastDropped++;
1789a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber        mVideoRenderer->render(mVideoBuffer);
1790a657f8deaf21acbe5faba7be1df9c6681d44d471Andreas Huber    }
1791bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1792f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    mVideoBuffer->release();
1793bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoBuffer = NULL;
1794bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
179564bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber    if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
1796a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(SEEK_PREVIEW, CLEAR);
17972b1222f8938356669672f35e0e53e176c78c40efAndreas Huber        return;
17982b1222f8938356669672f35e0e53e176c78c40efAndreas Huber    }
17992b1222f8938356669672f35e0e53e176c78c40efAndreas Huber
1800bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    postVideoEvent_l();
1801bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1802bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1803bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Hubervoid AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
1804bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mVideoEventPending) {
1805bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return;
1806bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1807bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
1808bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mVideoEventPending = true;
1809bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
1810bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1811bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
18125295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Hubervoid AwesomePlayer::postStreamDoneEvent_l(status_t status) {
1813bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    if (mStreamDoneEventPending) {
1814bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber        return;
1815bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    }
1816bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mStreamDoneEventPending = true;
18175295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber
18185295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    mStreamDoneStatus = status;
1819bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber    mQueue.postEvent(mStreamDoneEvent);
1820bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}
1821bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber
182266b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Hubervoid AwesomePlayer::postBufferingEvent_l() {
182366b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    if (mBufferingEventPending) {
182466b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber        return;
182566b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    }
182666b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mBufferingEventPending = true;
182766b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber    mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
182866b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber}
182966b0a35c9a4136a84c3f73b1b25fcb5220138b95Andreas Huber
1830145e68fc778275963189b02a1adcbe27cce4d769Andreas Hubervoid AwesomePlayer::postVideoLagEvent_l() {
1831145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    if (mVideoLagEventPending) {
1832145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber        return;
1833145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    }
1834145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mVideoLagEventPending = true;
1835145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
1836145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber}
1837145e68fc778275963189b02a1adcbe27cce4d769Andreas Huber
183802f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Hubervoid AwesomePlayer::postCheckAudioStatusEvent(int64_t delayUs) {
183902f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    Mutex::Autolock autoLock(mAudioLock);
18401862a33b246249630b654182afb5914da3480d4cAndreas Huber    if (mAudioStatusEventPending) {
18411862a33b246249630b654182afb5914da3480d4cAndreas Huber        return;
18421862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
18431862a33b246249630b654182afb5914da3480d4cAndreas Huber    mAudioStatusEventPending = true;
184484b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Huber    mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
18451862a33b246249630b654182afb5914da3480d4cAndreas Huber}
18461862a33b246249630b654182afb5914da3480d4cAndreas Huber
18471862a33b246249630b654182afb5914da3480d4cAndreas Hubervoid AwesomePlayer::onCheckAudioStatus() {
184802f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    {
184902f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        Mutex::Autolock autoLock(mAudioLock);
185002f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        if (!mAudioStatusEventPending) {
185102f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            // Event was dispatched and while we were blocking on the mutex,
185202f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            // has already been cancelled.
185302f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber            return;
185402f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        }
185502f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber
185602f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber        mAudioStatusEventPending = false;
1857d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber    }
1858d29345dfa29cdcc650f3705e43950ef2500f6728Andreas Huber
185902f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    Mutex::Autolock autoLock(mLock);
18601862a33b246249630b654182afb5914da3480d4cAndreas Huber
18611862a33b246249630b654182afb5914da3480d4cAndreas Huber    if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
18621862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioSeekComplete = false;
18631321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber
18641321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        if (!mSeekNotificationSent) {
18651321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber            notifyListener_l(MEDIA_SEEK_COMPLETE);
18661321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber            mSeekNotificationSent = true;
18671321fdd94d354431b930735e9f38f32ecd189a2dAndreas Huber        }
1868dac4ee72bac87388a1495e098f39d73168c8078fAndreas Huber
186964bb6983690bf994d904591145a3cdd6373bdbe6Andreas Huber        mSeeking = NO_SEEK;
18701862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
18711862a33b246249630b654182afb5914da3480d4cAndreas Huber
18725295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    status_t finalStatus;
18735295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber    if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
18741862a33b246249630b654182afb5914da3480d4cAndreas Huber        mWatchForAudioEOS = false;
1875a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(AUDIO_AT_EOS, SET);
1876a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        modifyFlags(FIRST_FRAME, SET);
18775295c0c55d41a2906ea7f65a3f22e6278cb17d4bAndreas Huber        postStreamDoneEvent_l(finalStatus);
18781862a33b246249630b654182afb5914da3480d4cAndreas Huber    }
18791862a33b246249630b654182afb5914da3480d4cAndreas Huber}
18801862a33b246249630b654182afb5914da3480d4cAndreas Huber
1881c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huberstatus_t AwesomePlayer::prepare() {
1882c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    Mutex::Autolock autoLock(mLock);
1883bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    return prepare_l();
1884bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber}
1885c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1886bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huberstatus_t AwesomePlayer::prepare_l() {
1887bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARED) {
1888bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return OK;
1889bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
1890bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1891bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARING) {
1892bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;
1893bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
1894bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1895bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mIsAsyncPrepare = false;
1896c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    status_t err = prepareAsync_l();
1897c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1898c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    if (err != OK) {
1899c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber        return err;
1900c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
1901c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1902bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    while (mFlags & PREPARING) {
1903c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber        mPreparedCondition.wait(mLock);
1904c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
1905c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1906bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    return mPrepareResult;
1907c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
1908c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1909c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huberstatus_t AwesomePlayer::prepareAsync() {
1910c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    Mutex::Autolock autoLock(mLock);
1911bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1912bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARING) {
1913bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;  // async prepare already pending
1914bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
1915bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
1916bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mIsAsyncPrepare = true;
1917c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    return prepareAsync_l();
1918c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
1919c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1920c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huberstatus_t AwesomePlayer::prepareAsync_l() {
1921bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mFlags & PREPARING) {
1922bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;  // async prepare already pending
1923c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
1924c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
19252e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    if (!mQueueStarted) {
19262e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        mQueue.start();
19272e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber        mQueueStarted = true;
19282e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber    }
19292e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
1930a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PREPARING, SET);
1931c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mAsyncPrepareEvent = new AwesomeEvent(
1932c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber            this, &AwesomePlayer::onPrepareAsyncEvent);
1933c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1934c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mQueue.postEvent(mAsyncPrepareEvent);
1935c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1936c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    return OK;
1937c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
1938c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
1939bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huberstatus_t AwesomePlayer::finishSetDataSource_l() {
1940e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    sp<DataSource> dataSource;
1941e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
1942681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    bool isWidevineStreaming = false;
1943681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (!strncasecmp("widevine://", mUri.string(), 11)) {
1944681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        isWidevineStreaming = true;
1945681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
1946681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        String8 newURI = String8("http://");
1947681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        newURI.append(mUri.string() + 11);
1948681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
1949681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mUri = newURI;
1950681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    }
1951681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
1952a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber    AString sniffedMIME;
1953a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
19548cb0c4168bf4b678e4a6edfcf409247016be20d5Andreas Huber    if (!strncasecmp("http://", mUri.string(), 7)
1955681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            || !strncasecmp("https://", mUri.string(), 8)
1956681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            || isWidevineStreaming) {
19571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mConnectingDataSource = HTTPBase::Create(
19581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                (mFlags & INCOGNITO)
19591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    ? HTTPBase::kFlagIncognito
19601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    : 0);
1961e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
19629b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        if (mUIDValid) {
19639b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber            mConnectingDataSource->setUID(mUID);
19649b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        }
19659b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
196649c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber        String8 cacheConfig;
196749c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber        bool disconnectAtHighwatermark;
196849c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber        NuCachedSource2::RemoveCacheSpecificHeaders(
196949c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
197049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber
1971e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mLock.unlock();
197279f77ef3b0a37660ba8c5bcb2dfbfda3860f2135Andreas Huber        status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
1973e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mLock.lock();
1974e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
1975e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        if (err != OK) {
1976e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            mConnectingDataSource.clear();
1977e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
1978df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("mConnectingDataSource->connect() returned %d", err);
1979e94bd14078d327ef2f800e69907efce641a13272Andreas Huber            return err;
1980e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        }
1981e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
1982681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (!isWidevineStreaming) {
1983681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            // The widevine extractor does its own caching.
1984681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
19850a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#if 0
1986681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            mCachedSource = new NuCachedSource2(
1987681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                    new ThrottledSource(
1988681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                        mConnectingDataSource, 50 * 1024 /* bytes/sec */));
19890a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#else
199049c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber            mCachedSource = new NuCachedSource2(
199149c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                    mConnectingDataSource,
199249c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                    cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
199349c59815369616b0fd5451ccabd377e8fe1dc3faAndreas Huber                    disconnectAtHighwatermark);
19940a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber#endif
1995681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
1996681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            dataSource = mCachedSource;
1997681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        } else {
1998681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            dataSource = mConnectingDataSource;
1999681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
2000681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2001e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        mConnectingDataSource.clear();
20020a5baa9b411fe086013d2a5e9126ed63fbad046cAndreas Huber
20036511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber        String8 contentType = dataSource->getMIMEType();
2004ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
20056511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber        if (strncasecmp(contentType.string(), "audio/", 6)) {
20066511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // We're not doing this for streams that appear to be audio-only
20076511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // streams to ensure that even low bandwidth streams start
20086511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // playing back fairly instantly.
2009ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
20106511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // We're going to prefill the cache before trying to instantiate
20116511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // the extractor below, as the latter is an operation that otherwise
20126511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // could block on the datasource for a significant amount of time.
20136511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // During that time we'd be unable to abort the preparation phase
20146511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            // without this prefill.
2015e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong            if (mCachedSource != NULL) {
2016e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // We're going to prefill the cache before trying to instantiate
2017e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // the extractor below, as the latter is an operation that otherwise
2018e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // could block on the datasource for a significant amount of time.
2019e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // During that time we'd be unable to abort the preparation phase
2020e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                // without this prefill.
2021e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong
2022e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                mLock.unlock();
2023e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong
2024bab412099ab1bd3e9e942453cbb42c87ea9a59ecAndreas Huber                // Initially make sure we have at least 192 KB for the sniff
2025a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                // to complete without blocking.
2026bab412099ab1bd3e9e942453cbb42c87ea9a59ecAndreas Huber                static const size_t kMinBytesForSniffing = 192 * 1024;
2027a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
2028a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                off64_t metaDataSize = -1ll;
2029e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                for (;;) {
2030e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    status_t finalStatus;
2031e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    size_t cachedDataRemaining =
2032e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                        mCachedSource->approxDataRemaining(&finalStatus);
2033e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong
2034a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (finalStatus != OK
2035a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                            || (metaDataSize >= 0
2036a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                                && cachedDataRemaining >= metaDataSize)
2037e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                            || (mFlags & PREPARE_CANCELLED)) {
2038e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                        break;
2039e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    }
20406511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
2041456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber                    ALOGV("now cached %d bytes of data", cachedDataRemaining);
2042a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
2043a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    if (metaDataSize < 0
2044a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                            && cachedDataRemaining >= kMinBytesForSniffing) {
2045a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        String8 tmp;
2046a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        float confidence;
2047a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        sp<AMessage> meta;
2048a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        if (!dataSource->sniff(&tmp, &confidence, &meta)) {
2049a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                            mLock.lock();
2050a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                            return UNKNOWN_ERROR;
2051a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        }
2052a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
2053a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // We successfully identified the file's extractor to
2054a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // be, remember this mime type so we don't have to
2055a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // sniff it again when we call MediaExtractor::Create()
2056a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        // below.
2057a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        sniffedMIME = tmp.string();
2058a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
2059a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        if (meta == NULL
2060a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                                || !meta->findInt64(
2061a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                                    "meta-data-size", &metaDataSize)) {
2062a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                            metaDataSize = kHighWaterMarkBytes;
2063a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        }
2064a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
2065a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                        CHECK_GE(metaDataSize, 0ll);
2066456caf3f5f0af673dc120c17c23635f40d8f5ac2Andreas Huber                        ALOGV("metaDataSize = %lld bytes", metaDataSize);
2067a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                    }
2068a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber
2069e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                    usleep(200000);
20706511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber                }
20716511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
2072e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                mLock.lock();
2073ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber            }
2074ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber
2075e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong            if (mFlags & PREPARE_CANCELLED) {
2076df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("Prepare cancelled while waiting for initial cache fill.");
2077e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong                return UNKNOWN_ERROR;
2078e39350924f4e743ec04cc9640526e06990c8cbdaJames Dong            }
2079ac05c317cd818701535c5d72ce90da98c4bae75bAndreas Huber        }
2080e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    } else {
2081e94bd14078d327ef2f800e69907efce641a13272Andreas Huber        dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
2082e94bd14078d327ef2f800e69907efce641a13272Andreas Huber    }
2083bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2084bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (dataSource == NULL) {
2085bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        return UNKNOWN_ERROR;
2086bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
2087bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2088681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    sp<MediaExtractor> extractor;
2089bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2090681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (isWidevineStreaming) {
2091681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        String8 mimeType;
2092681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        float confidence;
2093681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        sp<AMessage> dummy;
2094785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong        bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy);
2095681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2096681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (!success
2097681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                || strcasecmp(
2098681755fc0d0797506456f46a2a10555916d6be32Andreas Huber                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
2099681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            return ERROR_UNSUPPORTED;
2100681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
2101681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2102681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mWVMExtractor = new WVMExtractor(dataSource);
2103681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mWVMExtractor->setAdaptiveStreamingMode(true);
2104681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        extractor = mWVMExtractor;
2105681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    } else {
2106a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber        extractor = MediaExtractor::Create(
2107a0f2bf56e30f580535229fa6a58e7d48b762727cAndreas Huber                dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());
2108681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2109681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        if (extractor == NULL) {
2110681755fc0d0797506456f46a2a10555916d6be32Andreas Huber            return UNKNOWN_ERROR;
2111681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        }
2112bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
2113bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
2114785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
2115b5ce361d19e69fe156f7188c9ee0f4734b259874Gloria Wang
2116785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong    if (mDecryptHandle != NULL) {
2117785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong        CHECK(mDrmManagerClient);
2118785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
2119785ee06d106cd7958e0c151ebc6b7174d9ba861eJames Dong            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2120b371426ce4cf2fa6d8c3d1903b61322feb165d35Gloria Wang        }
2121dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang    }
2122dcd25efb46c41c8d24a0a9cf61fb57f84149709eGloria Wang
2123681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    status_t err = setDataSource_l(extractor);
2124681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2125681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    if (err != OK) {
2126681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        mWVMExtractor.clear();
2127681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2128681755fc0d0797506456f46a2a10555916d6be32Andreas Huber        return err;
2129681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    }
2130681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2131681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    return OK;
2132bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber}
2133bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
213488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Hubervoid AwesomePlayer::abortPrepare(status_t err) {
213588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    CHECK(err != OK);
213688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
213788d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    if (mIsAsyncPrepare) {
213888d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber        notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
213988d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    }
214088d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
214188d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mPrepareResult = err;
2142a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
214388d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mAsyncPrepareEvent = NULL;
214488d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber    mPreparedCondition.broadcast();
214588d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber}
214688d8a83de12592635248aa1a3bd6b9ea46108501Andreas Huber
2147e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber// static
2148e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huberbool AwesomePlayer::ContinuePreparation(void *cookie) {
2149e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber    AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
2150e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber
2151e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber    return (me->mFlags & PREPARE_CANCELLED) == 0;
2152e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber}
2153e966fb05c7e67a7f5dce65024de60aac83eb6f81Andreas Huber
2154c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Hubervoid AwesomePlayer::onPrepareAsyncEvent() {
21558650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    Mutex::Autolock autoLock(mLock);
2156bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
21578650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mFlags & PREPARE_CANCELLED) {
2158df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("prepare was cancelled before doing anything");
21598650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        abortPrepare(UNKNOWN_ERROR);
21608650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        return;
21618650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
2162e94bd14078d327ef2f800e69907efce641a13272Andreas Huber
21638650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mUri.size() > 0) {
21648650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        status_t err = finishSetDataSource_l();
2165bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
21668650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (err != OK) {
21678650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            abortPrepare(err);
21688650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            return;
2169bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        }
21708650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
2171bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber
21728650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mVideoTrack != NULL && mVideoSource == NULL) {
21738650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        status_t err = initVideoDecoder();
21741322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber
21758650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (err != OK) {
21768650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            abortPrepare(err);
21778650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            return;
21781322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber        }
21798650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
21801322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber
21818650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    if (mAudioTrack != NULL && mAudioSource == NULL) {
21828650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        status_t err = initAudioDecoder();
21831322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber
21848650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        if (err != OK) {
21858650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            abortPrepare(err);
21868650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber            return;
21871322e7ebc33e8e161fb73cd47e43dd93357608e4Andreas Huber        }
2188c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    }
2189c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2190a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PREPARING_CONNECTED, SET);
21916a05c9e912aeb8bfe1ef99516def91a177a481b6Andreas Huber
21922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (isStreamingHTTP()) {
21938650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        postBufferingEvent_l();
21948650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    } else {
21958650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber        finishAsyncPrepare_l();
21968650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber    }
21978650e1960905097f6f1d6aa462ccb1c93c656834Andreas Huber}
2198c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
21998650e1960905097f6f1d6aa462ccb1c93c656834Andreas Hubervoid AwesomePlayer::finishAsyncPrepare_l() {
2200bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    if (mIsAsyncPrepare) {
22015daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        if (mVideoSource == NULL) {
2202bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
2203bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        } else {
22045daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            notifyVideoSize_l();
2205bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        }
2206c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2207bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber        notifyListener_l(MEDIA_PREPARED);
2208bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    }
2209c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2210bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mPrepareResult = OK;
2211a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
2212a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    modifyFlags(PREPARED, SET);
2213c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber    mAsyncPrepareEvent = NULL;
2214bd22c52280179b29eefac91ef7e7bbbc33d25904Andreas Huber    mPreparedCondition.broadcast();
2215c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber}
2216c23f12af0394aa2f6651968a3c8840f1af317aa1Andreas Huber
2217acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huberuint32_t AwesomePlayer::flags() const {
2218acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber    return mExtractorFlags;
2219acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber}
2220acdd9d0f59c3d8bdc3de80664a609527ec3d21e2Andreas Huber
222184b343f29063fbfa2ee61b2e3d37ba059ca507d4Andreas Hubervoid AwesomePlayer::postAudioEOS(int64_t delayUs) {
222202f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    postCheckAudioStatusEvent(delayUs);
2223ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber}
2224ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
2225ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Hubervoid AwesomePlayer::postAudioSeekComplete() {
222602f6e988107bc13ebe4828b734ea0fc3d9d11ae0Andreas Huber    postCheckAudioStatusEvent(0);
2227ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber}
2228ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
22294f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t AwesomePlayer::setParameter(int key, const Parcel &request) {
2230965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    switch (key) {
2231965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        case KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX:
2232965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        {
2233965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            Mutex::Autolock autoLock(mTimedTextLock);
2234965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return setTimedTextTrackIndex(request.readInt32());
2235965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
2236965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE:
2237965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        {
2238965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            Mutex::Autolock autoLock(mTimedTextLock);
2239965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            if (mTextPlayer == NULL) {
2240965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
2241965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            }
2242965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
2243965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return mTextPlayer->setParameter(key, request);
2244965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
22455b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
22465b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        {
22475b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            return setCacheStatCollectFreq(request);
22485b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        }
2249965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        default:
2250965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        {
2251965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return ERROR_UNSUPPORTED;
2252965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
22537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
22544f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
22554f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang
22565b1b8a93a07326f1cbc627f09e02988375189e0aJames Dongstatus_t AwesomePlayer::setCacheStatCollectFreq(const Parcel &request) {
22575b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    if (mCachedSource != NULL) {
22585b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        int32_t freqMs = request.readInt32();
2259b8a805261bf0282e992d3608035e47d05a898710Steve Block        ALOGD("Request to keep cache stats in the past %d ms",
22605b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong            freqMs);
22615b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong        return mCachedSource->setCacheStatCollectFreq(freqMs);
22625b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    }
22635b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong    return ERROR_UNSUPPORTED;
22645b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong}
22655b1b8a93a07326f1cbc627f09e02988375189e0aJames Dong
22664f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t AwesomePlayer::getParameter(int key, Parcel *reply) {
2267cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    switch (key) {
2268cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
2269cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        {
2270cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            int32_t channelCount;
2271cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            if (mAudioTrack == 0 ||
2272cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten                    !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
2273cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten                channelCount = 0;
2274cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            }
2275cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            reply->writeInt32(channelCount);
2276cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        }
2277cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        return OK;
2278cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    default:
2279cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        {
2280cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten            return ERROR_UNSUPPORTED;
2281cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten        }
2282cd25fed09742235fac10953b9d4b77268c695063Glenn Kasten    }
22834f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
2284ed54ad0f8619ae416b0968ade6248894cbfc4dbaAndreas Huber
2285681755fc0d0797506456f46a2a10555916d6be32Andreas Huberbool AwesomePlayer::isStreamingHTTP() const {
2286681755fc0d0797506456f46a2a10555916d6be32Andreas Huber    return mCachedSource != NULL || mWVMExtractor != NULL;
2287681755fc0d0797506456f46a2a10555916d6be32Andreas Huber}
2288681755fc0d0797506456f46a2a10555916d6be32Andreas Huber
2289a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huberstatus_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
2290a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    Mutex::Autolock autoLock(mStatsLock);
2291a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2292a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    FILE *out = fdopen(dup(fd), "w");
2293a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2294a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fprintf(out, " AwesomePlayer\n");
2295a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mStats.mFd < 0) {
2296a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "  URI(%s)", mStats.mURI.string());
2297a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    } else {
2298a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "  fd(%d)", mStats.mFd);
2299a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2300a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2301a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fprintf(out, ", flags(0x%08x)", mStats.mFlags);
2302a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2303a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mStats.mBitrate >= 0) {
2304a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate);
2305a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2306a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2307a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fprintf(out, "\n");
2308a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2309a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
2310a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        const TrackStat &stat = mStats.mTracks.itemAt(i);
2311a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2312a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "  Track %d\n", i + 1);
2313a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "   MIME(%s)", stat.mMIME.string());
2314a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2315a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        if (!stat.mDecoderName.isEmpty()) {
2316a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            fprintf(out, ", decoder(%s)", stat.mDecoderName.string());
2317a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
2318a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2319a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        fprintf(out, "\n");
2320a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2321a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        if ((ssize_t)i == mStats.mVideoTrackIndex) {
2322a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            fprintf(out,
2323a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    "   videoDimensions(%d x %d), "
2324a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    "numVideoFramesDecoded(%lld), "
2325a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    "numVideoFramesDropped(%lld)\n",
2326a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mVideoWidth,
2327a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mVideoHeight,
2328a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mNumVideoFramesDecoded,
2329a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber                    mStats.mNumVideoFramesDropped);
2330a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        }
2331a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2332a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2333a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    fclose(out);
2334a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    out = NULL;
2335a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2336a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    return OK;
2337a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber}
2338a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2339a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Hubervoid AwesomePlayer::modifyFlags(unsigned value, FlagMode mode) {
2340a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    switch (mode) {
2341a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        case SET:
2342a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            mFlags |= value;
2343a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            break;
2344a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        case CLEAR:
2345a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            mFlags &= ~value;
2346a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            break;
2347a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        case ASSIGN:
2348a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            mFlags = value;
2349a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            break;
2350a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        default:
2351a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber            TRESPASS();
2352a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2353a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2354a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    {
2355a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        Mutex::Autolock autoLock(mStatsLock);
2356a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mStats.mFlags = mFlags;
2357a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
2358a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber}
2359a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber
2360bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber}  // namespace android
2361