AwesomePlayer.cpp revision ccd08439c7914d86264c7ad81bfd03cf39aaa9f7
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2009 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski *
8ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski * See the License for the specific language governing permissions and
141e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski * limitations under the License.
151e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski */
161e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski
17de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#undef DEBUG_HDCP
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
191e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski//#define LOG_NDEBUG 0
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define LOG_TAG "AwesomePlayer"
21de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#define ATRACE_TAG ATRACE_TAG_VIDEO
22de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski#include <utils/Log.h>
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Trace.h>
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <dlfcn.h>
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/AwesomePlayer.h"
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/DRMExtractor.h"
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/SoftwareRenderer.h"
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/NuCachedSource2.h"
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/ThrottledSource.h"
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/MPEG2TSExtractor.h"
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "include/WVMExtractor.h"
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <binder/IPCThreadState.h>
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <binder/IServiceManager.h>
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/IMediaPlayerService.h>
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/foundation/hexdump.h>
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/foundation/ADebug.h>
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/timedtext/TimedTextDriver.h>
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/AudioPlayer.h>
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/DataSource.h>
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/FileSource.h>
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/MediaBuffer.h>
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/MediaDefs.h>
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/MediaExtractor.h>
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/MediaSource.h>
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/MetaData.h>
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/OMXCodec.h>
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <gui/ISurfaceTexture.h>
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <gui/SurfaceTextureClient.h>
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <media/stagefright/foundation/AMessage.h>
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <cutils/properties.h>
57e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define USE_SURFACE_ALLOC 1
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define FRAME_DROP_FREQ 0
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskinamespace android {
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const size_t kLowWaterMarkBytes = 40000;
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic const size_t kHighWaterMarkBytes = 200000;
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct AwesomeEvent : public TimedEventQueue::Event {
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeEvent(
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            AwesomePlayer *player,
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            void (AwesomePlayer::*method)())
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        : mPlayer(player),
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski          mMethod(method) {
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprotected:
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual ~AwesomeEvent() {}
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        (mPlayer->*mMethod)();
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate:
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomePlayer *mPlayer;
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void (AwesomePlayer::*mMethod)();
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
8791447d88f2bdf9c2bf8d1a53570efef6172fba74Narayan Kamath    AwesomeEvent(const AwesomeEvent &);
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeEvent &operator=(const AwesomeEvent &);
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct AwesomeLocalRenderer : public AwesomeRenderer {
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeLocalRenderer(
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta)
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        : mTarget(new SoftwareRenderer(nativeWindow, meta)) {
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual void render(MediaBuffer *buffer) {
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        render((const uint8_t *)buffer->data() + buffer->range_offset(),
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski               buffer->range_length());
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void render(const void *data, size_t size) {
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTarget->render(data, size, NULL);
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprotected:
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual ~AwesomeLocalRenderer() {
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delete mTarget;
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTarget = NULL;
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate:
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    SoftwareRenderer *mTarget;
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeLocalRenderer(const AwesomeLocalRenderer &);
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);;
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct AwesomeNativeWindowRenderer : public AwesomeRenderer {
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeNativeWindowRenderer(
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            const sp<ANativeWindow> &nativeWindow,
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int32_t rotationDegrees)
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        : mNativeWindow(nativeWindow) {
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        applyRotation(rotationDegrees);
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual void render(MediaBuffer *buffer) {
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ATRACE_CALL();
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t timeUs;
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        native_window_set_buffers_timestamp(mNativeWindow.get(), timeUs * 1000);
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = mNativeWindow->queueBuffer(
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mNativeWindow.get(), buffer->graphicBuffer().get(), -1);
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != 0) {
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGE("queueBuffer failed with error %s (%d)", strerror(-err),
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    -err);
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MetaData> metaData = buffer->meta_data();
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        metaData->setInt32(kKeyRendered, 1);
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprotected:
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual ~AwesomeNativeWindowRenderer() {}
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate:
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<ANativeWindow> mNativeWindow;
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void applyRotation(int32_t rotationDegrees) {
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        uint32_t transform;
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        switch (rotationDegrees) {
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case 0: transform = 0; break;
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case 90: transform = HAL_TRANSFORM_ROT_90; break;
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case 180: transform = HAL_TRANSFORM_ROT_180; break;
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case 270: transform = HAL_TRANSFORM_ROT_270; break;
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            default: transform = 0; break;
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (transform) {
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            CHECK_EQ(0, native_window_set_buffers_transform(
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        mNativeWindow.get(), transform));
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &);
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomeNativeWindowRenderer &operator=(
168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            const AwesomeNativeWindowRenderer &);
169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// To collect the decoder usage
172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid addBatteryData(uint32_t params) {
173eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    sp<IBinder> binder =
174eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown        defaultServiceManager()->getService(String16("media.player"));
175eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
176eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    CHECK(service.get() != NULL);
177eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown
178eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    service->addBatteryData(params);
179eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown}
180eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown
181eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown////////////////////////////////////////////////////////////////////////////////
182eb490d6194bd79adbe144a1230fc126f4c180a2fJeff BrownAwesomePlayer::AwesomePlayer()
183eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    : mQueueStarted(false),
184eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mUIDValid(false),
185eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mTimeSource(NULL),
186eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mVideoRenderingStarted(false),
187eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mVideoRendererIsPreview(false),
188eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mAudioPlayer(NULL),
189eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mDisplayWidth(0),
190eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mDisplayHeight(0),
191eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
192eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mFlags(0),
193eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mExtractorFlags(0),
194eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mVideoBuffer(NULL),
195eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mDecryptHandle(NULL),
196eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mLastVideoTimeUs(-1),
197eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown      mTextDriver(NULL) {
198eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    CHECK_EQ(mClient.connect(), (status_t)OK);
199eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown
200eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    DataSource::RegisterDefaultSniffers();
201eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown
202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoEventPending = false;
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mStreamDoneEventPending = false;
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mBufferingEventPending = false;
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate);
2097cce7bb5d8d68e78a414c176dc89a803f706c9ceChet Haase    mVideoEventPending = false;
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mCheckAudioStatusEvent = new AwesomeEvent(
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            this, &AwesomePlayer::onCheckAudioStatus);
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioStatusEventPending = false;
215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    reset();
217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
219282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiAwesomePlayer::~AwesomePlayer() {
220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mQueueStarted) {
221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mQueue.stop();
222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    reset();
225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mClient.disconnect();
227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::cancelPlayerEvents(bool keepNotifications) {
230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mQueue.cancelEvent(mVideoEvent->eventID());
231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoEventPending = false;
232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mQueue.cancelEvent(mVideoLagEvent->eventID());
233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoLagEventPending = false;
234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!keepNotifications) {
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mQueue.cancelEvent(mStreamDoneEvent->eventID());
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStreamDoneEventPending = false;
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAudioStatusEventPending = false;
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mQueue.cancelEvent(mBufferingEvent->eventID());
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mBufferingEventPending = false;
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mListener = listener;
249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::setUID(uid_t uid) {
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGV("AwesomePlayer running on behalf of uid %d", uid);
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mUID = uid;
255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mUIDValid = true;
256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setDataSource(
259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const char *uri, const KeyedVector<String8, String8> *headers) {
26054de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    Mutex::Autolock autoLock(mLock);
26154de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    return setDataSource_l(uri, headers);
26254de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski}
26354de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski
26454de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinskistatus_t AwesomePlayer::setDataSource_l(
265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const char *uri, const KeyedVector<String8, String8> *headers) {
266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    reset_l();
267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mUri = uri;
269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (headers) {
271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mUriHeaders = *headers;
272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2734bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski        ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (index >= 0) {
275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // Browser is in "incognito" mode, suppress logging URLs.
276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // This isn't something that should be passed to the server.
278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mUriHeaders.removeItemsAt(index);
279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            modifyFlags(INCOGNITO, SET);
281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGI("setDataSource_l(URL suppressed)");
285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // The actual work will be done during preparation in the call to
287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ::finishSetDataSource_l to avoid blocking the calling thread in
288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // setDataSource for any significant time.
289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mFd = -1;
293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mURI = mUri;
294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setDataSource(
300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int fd, int64_t offset, int64_t length) {
301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    reset_l();
304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<DataSource> dataSource = new FileSource(fd, offset, length);
306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = dataSource->initCheck();
308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != OK) {
310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mFileSource = dataSource;
314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mFd = fd;
318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mURI = String8();
319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return setDataSource_l(dataSource);
322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return INVALID_OPERATION;
326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setDataSource_l(
329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const sp<DataSource> &dataSource) {
330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (extractor == NULL) {
333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return UNKNOWN_ERROR;
334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (extractor->getDrmFlag()) {
337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        checkDrmStatus(dataSource);
338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return setDataSource_l(extractor);
341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::checkDrmStatus(const sp<DataSource>& dataSource) {
344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDecryptHandle != NULL) {
346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        CHECK(mDrmManagerClient);
347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Attempt to approximate overall stream bitrate by summing all
355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // tracks' individual bitrates, if not all of them advertise bitrate,
356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // we have to fail.
357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t totalBitRate = 0;
359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mExtractor = extractor;
361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i = 0; i < extractor->countTracks(); ++i) {
362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MetaData> meta = extractor->getTrackMetaData(i);
363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int32_t bitrate;
365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            const char *mime;
367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            CHECK(meta->findCString(kKeyMIMEType, &mime));
368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGV("track of type '%s' does not publish bitrate", mime);
369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            totalBitRate = -1;
371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            break;
372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        totalBitRate += bitrate;
375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mBitrate = totalBitRate;
378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGV("mBitrate = %lld bits/sec", mBitrate);
380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mBitrate = mBitrate;
384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mTracks.clear();
385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mAudioTrackIndex = -1;
386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mVideoTrackIndex = -1;
387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool haveAudio = false;
390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool haveVideo = false;
391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i = 0; i < extractor->countTracks(); ++i) {
392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MetaData> meta = extractor->getTrackMetaData(i);
393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const char *_mime;
395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        CHECK(meta->findCString(kKeyMIMEType, &_mime));
396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 mime = String8(_mime);
398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!haveVideo && !strncasecmp(mime.string(), "video/", 6)) {
400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            setVideoSource(extractor->getTrack(i));
401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            haveVideo = true;
402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // Set the presentation/display size
404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int32_t displayWidth, displayHeight;
405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (success) {
407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (success) {
410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mDisplayWidth = displayWidth;
411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mDisplayHeight = displayHeight;
412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            {
415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Mutex::Autolock autoLock(mStatsLock);
416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mStats.mVideoTrackIndex = mStats.mTracks.size();
417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mStats.mTracks.push();
418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                TrackStat *stat =
419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                stat->mMIME = mime.string();
421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (!haveAudio && !strncasecmp(mime.string(), "audio/", 6)) {
423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            setAudioSource(extractor->getTrack(i));
424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            haveAudio = true;
425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mActiveAudioTrackIndex = i;
426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            {
428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Mutex::Autolock autoLock(mStatsLock);
429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mStats.mAudioTrackIndex = mStats.mTracks.size();
430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mStats.mTracks.push();
431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                TrackStat *stat =
432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                stat->mMIME = mime.string();
434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_AUDIO_VORBIS)) {
437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // Only do this for vorbis audio, none of the other audio
438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // formats even support this ringtone specific hack and
439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // retrieving the metadata on some extractors may turn out
440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // to be very expensive.
441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                sp<MetaData> fileMeta = extractor->getMetaData();
442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                int32_t loop;
443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (fileMeta != NULL
444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        && fileMeta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    modifyFlags(AUTO_LOOPING, SET);
446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            addTextSource_l(i, extractor->getTrack(i));
450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!haveAudio && !haveVideo) {
454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mWVMExtractor != NULL) {
455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return mWVMExtractor->getError();
456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return UNKNOWN_ERROR;
458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mExtractorFlags = extractor->flags();
4624bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski
463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::reset() {
467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    reset_l();
469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::reset_l() {
472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoRenderingStarted = false;
473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mActiveAudioTrackIndex = -1;
474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mDisplayWidth = 0;
475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mDisplayHeight = 0;
476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDecryptHandle != NULL) {
478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    Playback::STOP, 0);
480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mDecryptHandle = NULL;
481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mDrmManagerClient = NULL;
482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & PLAYING) {
485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            params |= IMediaPlayerService::kBatteryDataTrackAudio;
488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mVideoSource != NULL) {
490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            params |= IMediaPlayerService::kBatteryDataTrackVideo;
491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        addBatteryData(params);
493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & PREPARING) {
496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(PREPARE_CANCELLED, SET);
497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mConnectingDataSource != NULL) {
498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("interrupting the connection process");
499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mConnectingDataSource->disconnect();
500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mFlags & PREPARING_CONNECTED) {
503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // We are basically done preparing, we're just buffering
504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // enough data to start playback, we can safely interrupt that.
505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            finishAsyncPrepare_l();
506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (mFlags & PREPARING) {
510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mPreparedCondition.wait(mLock);
511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    cancelPlayerEvents();
514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
5154bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski    mWVMExtractor.clear();
516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mCachedSource.clear();
517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioTrack.clear();
518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoTrack.clear();
519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mExtractor.clear();
520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Shutdown audio first, so that the respone to the reset request
522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // appears to happen instantaneously as far as the user is concerned
523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // If we did this later, audio would continue playing while we
524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // shutdown the video-related resources and the player appear to
525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // not be as responsive to a reset request.
526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            && mAudioSource != NULL) {
528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // If we had an audio player, it would have effectively
529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // taken possession of the audio source and stopped it when
530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // _it_ is stopped. Otherwise this is still our responsibility.
531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAudioSource->stop();
532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioSource.clear();
534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mTimeSource = NULL;
536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    delete mAudioPlayer;
538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioPlayer = NULL;
539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mTextDriver != NULL) {
541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delete mTextDriver;
542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTextDriver = NULL;
543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoRenderer.clear();
546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoSource != NULL) {
548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        shutdownVideoDecoder_l();
549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mDurationUs = -1;
552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(0, ASSIGN);
553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mExtractorFlags = 0;
554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mTimeSourceDeltaUs = 0;
555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoTimeUs = 0;
556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeeking = NO_SEEK;
558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeekNotificationSent = true;
559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeekTimeUs = 0;
560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mUri.setTo("");
562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mUriHeaders.clear();
563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mFileSource.clear();
565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mBitrate = -1;
567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mLastVideoTimeUs = -1;
568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mFd = -1;
572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mURI = String8();
573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mBitrate = -1;
574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mAudioTrackIndex = -1;
575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mVideoTrackIndex = -1;
576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mNumVideoFramesDecoded = 0;
577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mNumVideoFramesDropped = 0;
578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mVideoWidth = -1;
579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mVideoHeight = -1;
580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mFlags = 0;
581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mTracks.clear();
582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mWatchForAudioSeekComplete = false;
585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mWatchForAudioEOS = false;
586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mListener != NULL) {
590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MediaPlayerBase> listener = mListener.promote();
591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (listener != NULL) {
593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            listener->sendEvent(msg, ext1, ext2);
594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool AwesomePlayer::getBitrate(int64_t *bitrate) {
599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    off64_t size;
600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDurationUs >= 0 && mCachedSource != NULL
601f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski            && mCachedSource->getSize(&size) == OK) {
602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
605f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski
606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mBitrate >= 0) {
607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *bitrate = mBitrate;
608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    *bitrate = 0;
612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return false;
614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Returns true iff cached duration is available/applicable.
617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t bitrate;
619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mCachedSource != NULL && getBitrate(&bitrate)) {
621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t finalStatus;
622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *eos = (finalStatus != OK);
625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (mWVMExtractor != NULL) {
627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t finalStatus;
628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *durationUs = mWVMExtractor->getCachedDurationUs(&finalStatus);
629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *eos = (finalStatus != OK);
630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
631f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski    }
632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return false;
634f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski}
635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::ensureCacheIsFetching_l() {
637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mCachedSource != NULL) {
638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mCachedSource->resumeFetchingIfNecessary();
639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::onVideoLagUpdate() {
643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!mVideoLagEventPending) {
645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoLagEventPending = false;
648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs();
650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t videoLateByUs = audioTimeUs - mVideoTimeUs;
651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) {
653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("video late by %lld ms.", videoLateByUs / 1000ll);
654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        notifyListener_l(
656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                MEDIA_INFO,
657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                MEDIA_INFO_VIDEO_TRACK_LAGGING,
658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                videoLateByUs / 1000ll);
659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    postVideoLagEvent_l();
662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::onBufferingUpdate() {
665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!mBufferingEventPending) {
667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mBufferingEventPending = false;
670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mCachedSource != NULL) {
672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t finalStatus;
673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bool eos = (finalStatus != OK);
675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (eos) {
677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (finalStatus == ERROR_END_OF_STREAM) {
678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mFlags & PREPARING) {
681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                ALOGV("cache has reached EOS, prepare is done.");
682df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                finishAsyncPrepare_l();
683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
684df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson        } else {
685df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson            int64_t bitrate;
686df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson            if (getBitrate(&bitrate)) {
687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                size_t cachedSize = mCachedSource->cachedSize();
688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
689df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson
690df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (percentage > 100) {
692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    percentage = 100;
693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } else {
697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // We don't know the bitrate of the stream, use absolute size
698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // limits to maintain the cache.
699df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson
700df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                if ((mFlags & PLAYING) && !eos
701df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
702df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                    ALOGI("cache is running low (< %d) , pausing.",
703df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                         kLowWaterMarkBytes);
704df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                    modifyFlags(CACHE_UNDERRUN, SET);
705df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                    pause_l();
706df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                    ensureCacheIsFetching_l();
707df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                    sendCacheStats();
708df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (mFlags & CACHE_UNDERRUN) {
711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        ALOGI("cache has filled up (> %d), resuming.",
712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                             kHighWaterMarkBytes);
713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        modifyFlags(CACHE_UNDERRUN, CLEAR);
714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        play_l();
715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } else if (mFlags & PREPARING) {
716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        ALOGV("cache has filled up (> %d), prepare is done",
717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                             kHighWaterMarkBytes);
718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        finishAsyncPrepare_l();
719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (mWVMExtractor != NULL) {
724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t finalStatus;
725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t cachedDurationUs
727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            = mWVMExtractor->getCachedDurationUs(&finalStatus);
728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bool eos = (finalStatus != OK);
730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (eos) {
732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (finalStatus == ERROR_END_OF_STREAM) {
733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mFlags & PREPARING) {
736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                ALOGV("cache has reached EOS, prepare is done.");
737df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson                finishAsyncPrepare_l();
738df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson            }
739df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson        } else {
740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (percentage > 100) {
742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                percentage = 100;
743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t cachedDurationUs;
750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool eos;
751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("cachedDurationUs = %.2f secs, eos=%d",
753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski             cachedDurationUs / 1E6, eos);
754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if ((mFlags & PLAYING) && !eos
756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && (cachedDurationUs < kLowWaterMarkUs)) {
757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            modifyFlags(CACHE_UNDERRUN, SET);
758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("cache is running low (%.2f secs) , pausing.",
759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                  cachedDurationUs / 1E6);
760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            pause_l();
761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ensureCacheIsFetching_l();
762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            sendCacheStats();
763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mFlags & CACHE_UNDERRUN) {
766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                modifyFlags(CACHE_UNDERRUN, CLEAR);
767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                ALOGI("cache has filled up (%.2f secs), resuming.",
768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                      cachedDurationUs / 1E6);
769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                play_l();
770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } else if (mFlags & PREPARING) {
771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                ALOGV("cache has filled up (%.2f secs), prepare is done",
772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                     cachedDurationUs / 1E6);
773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                finishAsyncPrepare_l();
774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
777df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson
778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    postBufferingEvent_l();
779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
780df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson
781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::sendCacheStats() {
7826a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski    sp<MediaPlayerBase> listener = mListener.promote();
7836a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski    if (listener != NULL) {
7846a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski        int32_t kbps = 0;
7856a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski        status_t err = UNKNOWN_ERROR;
7866a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski        if (mCachedSource != NULL) {
7876a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski            err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (mWVMExtractor != NULL) {
7896a7d2757a936ee79b8dba2055139c8b71130c58eAdam Lesinski            err = mWVMExtractor->getEstimatedBandwidthKbps(&kbps);
790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
791df08d1c24dbbc242978ee33416d1e54998f88915Jeff Davidson        if (err == OK) {
792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            listener->sendEvent(
79382a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski                MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
79482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        }
79582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski    }
79682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski}
79782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski
79882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinskivoid AwesomePlayer::onStreamDone() {
799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Posted whenever any stream finishes playing.
800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
80182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski
802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!mStreamDoneEventPending) {
804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mStreamDoneEventPending = false;
807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("MEDIA_ERROR %d", mStreamDoneStatus);
810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        notifyListener_l(
812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, mStreamDoneStatus);
813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        pause_l(true /* at eos */);
815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(AT_EOS, SET);
817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const bool allDone =
821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        (mVideoSource == NULL || (mFlags & VIDEO_AT_EOS))
822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            && (mAudioSource == NULL || (mFlags & AUDIO_AT_EOS));
823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
82482a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski    if (!allDone) {
82582a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        return;
82682a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski    }
82782a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski
82882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski    if ((mFlags & LOOPING)
82982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski            || ((mFlags & AUTO_LOOPING)
83082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski                && (mAudioSink == NULL || mAudioSink->realtime()))) {
83182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        // Don't AUTO_LOOP if we're being recorded, since that cannot be
832ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        // turned off and recording would go on indefinitely.
833ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
834ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        seekTo_l(0);
835ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
836ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        if (mVideoSource != NULL) {
837ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            postVideoEvent_l();
838ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        }
839ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    } else {
840ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        ALOGV("MEDIA_PLAYBACK_COMPLETE");
841ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
842ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
843ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        pause_l(true /* at eos */);
844ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
845ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        modifyFlags(AT_EOS, SET);
846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::play() {
850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(CACHE_UNDERRUN, CLEAR);
855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return play_l();
857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::play_l() {
860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(SEEK_PREVIEW, CLEAR);
861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & PLAYING) {
863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OK;
864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!(mFlags & PREPARED)) {
867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = prepare_l();
868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != OK) {
870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return err;
871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(PLAYING, SET);
875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(FIRST_FRAME, SET);
876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDecryptHandle != NULL) {
878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t position;
879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        getPosition(&position);
880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Playback::START, position / 1000);
882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioSource != NULL) {
885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mAudioPlayer == NULL) {
886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mAudioSink != NULL) {
887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                bool allowDeepBuffering;
888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                int64_t cachedDurationUs;
889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                bool eos;
890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (mVideoSource == NULL
891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        && (mDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US ||
892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        (getCachedDuration_l(&cachedDurationUs, &eos) &&
893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        cachedDurationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US))) {
894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    allowDeepBuffering = true;
895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                } else {
896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    allowDeepBuffering = false;
897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mAudioPlayer = new AudioPlayer(mAudioSink, allowDeepBuffering, this);
900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mAudioPlayer->setSource(mAudioSource);
901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mTimeSource = mAudioPlayer;
903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // If there was a seek request before we ever started,
905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // honor the request now.
906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // Make sure to do this before starting the audio player
907833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski                // to avoid a race condition.
908833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski                seekAudioIfNecessary_l();
909833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            }
910833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski        }
911833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski
912833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski        CHECK(!(mFlags & AUDIO_RUNNING));
913833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski
914833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski        if (mVideoSource == NULL) {
915833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            // We don't want to post an error notification at this point,
916833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            // the error returned from MediaPlayer::start() will suffice.
917833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski
918833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            status_t err = startAudioPlayer_l(
919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    false /* sendErrorNotification */);
920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (err != OK) {
922ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                delete mAudioPlayer;
923ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                mAudioPlayer = NULL;
924ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
925ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                modifyFlags((PLAYING | FIRST_FRAME), CLEAR);
926ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
927ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                if (mDecryptHandle != NULL) {
928ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                    mDrmManagerClient->setPlaybackStatus(
929ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                            mDecryptHandle, Playback::STOP, 0);
930ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                }
931ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
932ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                return err;
933ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            }
934ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        }
935ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
936ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
937ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (mTimeSource == NULL && mAudioPlayer == NULL) {
938ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        mTimeSource = &mSystemTimeSource;
939ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
940ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
941ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (mVideoSource != NULL) {
942ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        // Kick off video playback
943ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        postVideoEvent_l();
944ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
945ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        if (mAudioSource != NULL && mVideoSource != NULL) {
946ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            postVideoLagEvent_l();
947ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        }
948ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
949ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
950ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (mFlags & AT_EOS) {
951ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        // Legacy behaviour, if a stream finishes playing and then
952ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        // is started again, we play from the start...
953ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        seekTo_l(0);
954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted
957ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        | IMediaPlayerService::kBatteryDataTrackDecoder;
958ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
959ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        params |= IMediaPlayerService::kBatteryDataTrackAudio;
960ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
961ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (mVideoSource != NULL) {
962ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        params |= IMediaPlayerService::kBatteryDataTrackVideo;
963ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
964ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    addBatteryData(params);
965ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
966ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    return OK;
967ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski}
968ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
969ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskistatus_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) {
970ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    CHECK(!(mFlags & AUDIO_RUNNING));
971ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
972ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (mAudioSource == NULL || mAudioPlayer == NULL) {
973ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        return OK;
974ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
975ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
976ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (!(mFlags & AUDIOPLAYER_STARTED)) {
977ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        bool wasSeeking = mAudioPlayer->isSeeking();
978ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
979ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        // We've already started the MediaSource in order to enable
980ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        // the prefetcher to read its data.
981ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        status_t err = mAudioPlayer->start(
982ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                true /* sourceAlreadyStarted */);
983ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
984ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        if (err != OK) {
985ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            if (sendErrorNotification) {
986ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
987ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            }
988ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
989ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            return err;
990ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        }
991ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
992ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        modifyFlags(AUDIOPLAYER_STARTED, SET);
993ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
994ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        if (wasSeeking) {
995ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            CHECK(!mAudioPlayer->isSeeking());
996ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
997ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            // We will have finished the seek while starting the audio player.
998ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            postAudioSeekComplete();
99982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        }
100082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski    } else {
1001ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        mAudioPlayer->resume();
1002ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
1003ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1004ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    modifyFlags(AUDIO_RUNNING, SET);
1005ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1006ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    mWatchForAudioEOS = true;
1007ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1008ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    return OK;
1009ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski}
1010ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1011ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinskivoid AwesomePlayer::notifyVideoSize_l() {
1012ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    ATRACE_CALL();
1013ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    sp<MetaData> meta = mVideoSource->getFormat();
1014ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1015ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    int32_t cropLeft, cropTop, cropRight, cropBottom;
1016ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    if (!meta->findRect(
1017ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                kKeyCropRect, &cropLeft, &cropTop, &cropRight, &cropBottom)) {
1018ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        int32_t width, height;
1019ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        CHECK(meta->findInt32(kKeyWidth, &width));
1020ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        CHECK(meta->findInt32(kKeyHeight, &height));
1021ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        cropLeft = cropTop = 0;
1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        cropRight = width - 1;
1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        cropBottom = height - 1;
1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("got dimensions only %d x %d", width, height);
1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("got crop rect %d, %d, %d, %d",
1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski             cropLeft, cropTop, cropRight, cropBottom);
1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int32_t displayWidth;
1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDisplayWidth = displayWidth;
1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int32_t displayHeight;
1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDisplayHeight = displayHeight;
1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int32_t usableWidth = cropRight - cropLeft + 1;
1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int32_t usableHeight = cropBottom - cropTop + 1;
1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDisplayWidth != 0) {
1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        usableWidth = mDisplayWidth;
1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDisplayHeight != 0) {
1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        usableHeight = mDisplayHeight;
1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mVideoWidth = usableWidth;
1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mVideoHeight = usableHeight;
1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int32_t rotationDegrees;
10592cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey    if (!mVideoTrack->getFormat()->findInt32(
10602cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey                kKeyRotation, &rotationDegrees)) {
1061fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        rotationDegrees = 0;
1062fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
1063fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1064fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (rotationDegrees == 90 || rotationDegrees == 270) {
1065fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        notifyListener_l(
1066fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                MEDIA_SET_VIDEO_SIZE, usableHeight, usableWidth);
1067fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else {
1068fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        notifyListener_l(
10692cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey                MEDIA_SET_VIDEO_SIZE, usableWidth, usableHeight);
10702cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey    }
10712cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey}
10722cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey
10732cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkeyvoid AwesomePlayer::initRenderer_l() {
10742cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey    ATRACE_CALL();
10752cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey
10762cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey    if (mNativeWindow == NULL) {
10772cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey        return;
10782cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey    }
10792cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey
10802cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey    sp<MetaData> meta = mVideoSource->getFormat();
10812cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey
1082fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    int32_t format;
108354de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    const char *component;
108454de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    int32_t decodedWidth, decodedHeight;
108554de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    CHECK(meta->findInt32(kKeyColorFormat, &format));
108654de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    CHECK(meta->findCString(kKeyDecoderComponent, &component));
108754de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    CHECK(meta->findInt32(kKeyWidth, &decodedWidth));
108854de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    CHECK(meta->findInt32(kKeyHeight, &decodedHeight));
108954de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski
109054de298c01ad79fe7f5850eb7aefc2542dd8d5daAdam Lesinski    int32_t rotationDegrees;
1091fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (!mVideoTrack->getFormat()->findInt32(
10926240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski                kKeyRotation, &rotationDegrees)) {
10936240840387335632fdc92d5d168f924e2f414ddaAdam Lesinski        rotationDegrees = 0;
1094fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
1095fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1096fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    mVideoRenderer.clear();
1097fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
109878a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey    // Must ensure that mVideoRenderer's destructor is actually executed
109978a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey    // before creating a new one.
110078a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey    IPCThreadState::self()->flushCommands();
110178a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey
110278a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey    // Even if set scaling mode fails, we will continue anyway
110378a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey    setVideoScalingMode_l(mVideoScalingMode);
110478a130144bdd047665f00782c481d31edb3e5fb7Jeff Sharkey    if (USE_SURFACE_ALLOC
1105fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            && !strncmp(component, "OMX.", 4)
1106fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            && strncmp(component, "OMX.google.", 11)
1107fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            && strcmp(component, "OMX.Nvidia.mpeg2v.decode")) {
1108e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        // Hardware decoders avoid the CPU color conversion by decoding
11092cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey        // directly to ANativeBuffers, so we must use a renderer that
1110fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        // just pushes those buffers to the ANativeWindow.
1111fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mVideoRenderer =
1112fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);
1113fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    } else {
1114fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        // Other decoders are instantiated locally and as a consequence
1115fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        // allocate their buffers in local address space.  This renderer
1116fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        // then performs a color conversion and copy to get the data
1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // into the ANativeBuffer.
1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mVideoRenderer = new AwesomeLocalRenderer(mNativeWindow, meta);
1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::pause() {
1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(CACHE_UNDERRUN, CLEAR);
1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return pause_l();
1130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::pause_l(bool at_eos) {
1133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!(mFlags & PLAYING)) {
1134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OK;
1135833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski    }
1136833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski
1137833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski    cancelPlayerEvents(true /* keepNotifications */);
1138833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski
1139833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski    if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1140833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski        if (at_eos) {
1141833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            // If we played the audio stream to completion we
1142833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            // want to make sure that all samples remaining in the audio
1143833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            // track's queue are played out.
1144833f3ccbc8f4dd1ec8abb9121988b99ff34ec4c1Adam Lesinski            mAudioPlayer->pause(true /* playPendingSamples */);
1145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
1146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mAudioPlayer->pause();
1147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(AUDIO_RUNNING, CLEAR);
1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & TEXTPLAYER_INITIALIZED) {
1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTextDriver->pause();
1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(TEXT_RUNNING, CLEAR);
1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(PLAYING, CLEAR);
1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDecryptHandle != NULL) {
1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Playback::PAUSE, 0);
1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    uint32_t params = IMediaPlayerService::kBatteryDataTrackDecoder;
1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) {
1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        params |= IMediaPlayerService::kBatteryDataTrackAudio;
1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoSource != NULL) {
1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        params |= IMediaPlayerService::kBatteryDataTrackVideo;
1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    addBatteryData(params);
1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool AwesomePlayer::isPlaying() const {
1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err;
1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (surfaceTexture != NULL) {
1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = setNativeWindow_l(new SurfaceTextureClient(surfaceTexture));
1187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
1188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = setNativeWindow_l(NULL);
1189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
1192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::shutdownVideoDecoder_l() {
1195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoBuffer) {
1196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mVideoBuffer->release();
1197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mVideoBuffer = NULL;
1198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoSource->stop();
1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // The following hack is necessary to ensure that the OMX
1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // component is completely released by the time we may try
1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // to instantiate it again.
1205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    wp<MediaSource> tmp = mVideoSource;
1206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoSource.clear();
1207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (tmp.promote() != NULL) {
1208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        usleep(1000);
1209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    IPCThreadState::self()->flushCommands();
1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGV("video decoder shutdown completed");
1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setNativeWindow_l(const sp<ANativeWindow> &native) {
1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mNativeWindow = native;
1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoSource == NULL) {
1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OK;
1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGV("attempting to reconfigure to use new surface");
1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool wasPlaying = (mFlags & PLAYING) != 0;
1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    pause_l();
1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoRenderer.clear();
1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    shutdownVideoDecoder_l();
1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = initVideoDecoder();
1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != OK) {
1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGE("failed to reinstantiate video decoder after surface change.");
1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mLastVideoTimeUs >= 0) {
1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSeeking = SEEK;
1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSeekTimeUs = mLastVideoTimeUs;
1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (wasPlaying) {
1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        play_l();
1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::setAudioSink(
1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const sp<MediaPlayerBase::AudioSink> &audioSink) {
1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioSink = audioSink;
1255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setLooping(bool shouldLoop) {
1258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
1259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(LOOPING, CLEAR);
1261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (shouldLoop) {
1263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(LOOPING, SET);
1264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::getDuration(int64_t *durationUs) {
1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mMiscStateLock);
1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDurationUs < 0) {
1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return UNKNOWN_ERROR;
1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    *durationUs = mDurationUs;
1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::getPosition(int64_t *positionUs) {
1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mSeeking != NO_SEEK) {
1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *positionUs = mSeekTimeUs;
1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (mVideoSource != NULL
1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            && (mAudioPlayer == NULL || !(mFlags & VIDEO_AT_EOS))) {
1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mMiscStateLock);
1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *positionUs = mVideoTimeUs;
1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (mAudioPlayer != NULL) {
1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *positionUs = mAudioPlayer->getMediaTimeUs();
1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        *positionUs = 0;
1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::seekTo(int64_t timeUs) {
1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mLock);
1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return seekTo_l(timeUs);
1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::seekTo_l(int64_t timeUs) {
1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & CACHE_UNDERRUN) {
1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(CACHE_UNDERRUN, CLEAR);
1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        play_l();
1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mFlags & PLAYING) && mVideoSource != NULL && (mFlags & VIDEO_AT_EOS)) {
1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // Video playback completed before, there's no pending
1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // video event right now. In order for this new seek
1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // to be honored, we need to post one.
1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        postVideoEvent_l();
1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeeking = SEEK;
1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeekNotificationSent = false;
1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeekTimeUs = timeUs;
1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    seekAudioIfNecessary_l();
1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & TEXTPLAYER_INITIALIZED) {
1330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTextDriver->seekToAsync(mSeekTimeUs);
1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!(mFlags & PLAYING)) {
1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("seeking while paused, sending SEEK_COMPLETE notification"
1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski             " immediately.");
1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        notifyListener_l(MEDIA_SEEK_COMPLETE);
1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSeekNotificationSent = true;
1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if ((mFlags & PREPARED) && mVideoSource != NULL) {
1341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            modifyFlags(SEEK_PREVIEW, SET);
1342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            postVideoEvent_l();
1343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::seekAudioIfNecessary_l() {
1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAudioPlayer->seekTo(mSeekTimeUs);
1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWatchForAudioSeekComplete = true;
1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWatchForAudioEOS = true;
1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1356e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        if (mDecryptHandle != NULL) {
1357e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    Playback::PAUSE, 0);
1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    Playback::START, mSeekTimeUs / 1000);
1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::setAudioSource(sp<MediaSource> source) {
1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(source != NULL);
1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioTrack = source;
1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::addTextSource_l(size_t trackIndex, const sp<MediaSource>& source) {
1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(source != NULL);
1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mTextDriver == NULL) {
1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTextDriver = new TimedTextDriver(mListener);
1376e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    }
1377e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mTextDriver->addInBandTextSource(trackIndex, source);
1379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::initAudioDecoder() {
1382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<MetaData> meta = mAudioTrack->getFormat();
1385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char *mime;
1387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(meta->findCString(kKeyMIMEType, &mime));
1388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAudioSource = mAudioTrack;
1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
1392e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        mAudioSource = OMXCodec::Create(
1393e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski                mClient.interface(), mAudioTrack->getFormat(),
1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                false, // createEncoder
1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mAudioTrack);
1396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioSource != NULL) {
1399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t durationUs;
1400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mAudioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Mutex::Autolock autoLock(mMiscStateLock);
1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mDurationUs < 0 || durationUs > mDurationUs) {
1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mDurationUs = durationUs;
1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = mAudioSource->start();
1408e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1409e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        if (err != OK) {
1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mAudioSource.clear();
1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return err;
1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // For legacy reasons we're simply going to ignore the absence
1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // of an audio decoder for QCELP instead of aborting playback
1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // altogether.
1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OK;
1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioSource != NULL) {
1421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
1422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mAudioTrackIndex);
1423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const char *component;
1424e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        if (!mAudioSource->getFormat()
1425e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski                ->findCString(kKeyDecoderComponent, &component)) {
1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            component = "none";
1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        stat->mDecoderName = component;
1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::setVideoSource(sp<MediaSource> source) {
1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(source != NULL);
1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoTrack = source;
1439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1440e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1441e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinskistatus_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Either the application or the DRM system can independently say
1445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // that there must be a hardware-protected path to an external video sink.
1446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // For now we always require a hardware-protected path to external video sink
1447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // if content is DRMed, but eventually this could be optional per DRM agent.
1448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // When the application wants protection, then
1449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    //   (USE_SURFACE_ALLOC && (mSurface != 0) &&
1450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    //   (mSurface->getFlags() & ISurfaceComposer::eProtectedByApp))
1451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // will be true, but that part is already handled by SurfaceFlinger.
1452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef DEBUG_HDCP
1454fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // For debugging, we allow a system property to control the protected usage.
1455fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    // In case of uninitialized or unexpected property, we default to "DRM only".
1456e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    bool setProtectionBit = false;
1457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    char value[PROPERTY_VALUE_MAX];
1458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (property_get("persist.sys.hdcp_checking", value, NULL)) {
1459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!strcmp(value, "never")) {
1460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // nop
1461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (!strcmp(value, "always")) {
1462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            setProtectionBit = true;
1463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (!strcmp(value, "drm-only")) {
1464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mDecryptHandle != NULL) {
1465fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                setProtectionBit = true;
1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // property value is empty, or unexpected value
1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mDecryptHandle != NULL) {
1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                setProtectionBit = true;
1471e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            }
1472e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        }
1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // can' read property value
1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mDecryptHandle != NULL) {
1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            setProtectionBit = true;
1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // note that usage bit is already cleared, so no need to clear it in the "else" case
1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (setProtectionBit) {
1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        flags |= OMXCodec::kEnableGrallocUsageProtected;
1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else
1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDecryptHandle != NULL) {
1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        flags |= OMXCodec::kEnableGrallocUsageProtected;
1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
1488e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    ALOGV("initVideoDecoder flags=0x%x", flags);
1489e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    mVideoSource = OMXCodec::Create(
1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mClient.interface(), mVideoTrack->getFormat(),
1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            false, // createEncoder
1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mVideoTrack,
1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            NULL, flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);
1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoSource != NULL) {
1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t durationUs;
1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mVideoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Mutex::Autolock autoLock(mMiscStateLock);
1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mDurationUs < 0 || durationUs > mDurationUs) {
1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mDurationUs = durationUs;
1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = mVideoSource->start();
1505e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1506e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        if (err != OK) {
1507e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            ALOGE("failed to start video source");
1508e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            mVideoSource.clear();
1509e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            return err;
1510e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        }
1511e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    }
1512e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1513e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    if (mVideoSource != NULL) {
1514e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        const char *componentName;
1515e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        CHECK(mVideoSource->getFormat()
1516e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski                ->findCString(kKeyDecoderComponent, &componentName));
1517e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1518e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski        {
1519e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            Mutex::Autolock autoLock(mStatsLock);
1520e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski            TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            stat->mDecoderName = componentName;
1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        static const char *kPrefix = "OMX.Nvidia.";
1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        static const char *kSuffix = ".decode";
1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        static const size_t kSuffixLength = strlen(kSuffix);
1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1529ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        size_t componentNameLength = strlen(componentName);
1530ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1531ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        if (!strncmp(componentName, kPrefix, strlen(kPrefix))
1532ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                && componentNameLength >= kSuffixLength
1533ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                && !strcmp(&componentName[
1534ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski                    componentNameLength - kSuffixLength], kSuffix)) {
1535ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski            modifyFlags(SLOW_DECODER_HACK, SET);
1536ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski        }
1537ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    }
1538ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski
1539ad2d07d2d98a46babb2a9472413fe9ce5080ca76Adam Lesinski    return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mSeeking == SEEK_VIDEO_ONLY) {
1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSeeking = NO_SEEK;
1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1553e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski
1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioPlayer != NULL) {
1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGV("seeking audio to %lld us (%.2f secs).", videoTimeUs, videoTimeUs / 1E6);
1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // If we don't have a video time, seek audio to the originally
155882a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        // requested seek time instead.
155982a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski
156082a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        mAudioPlayer->seekTo(videoTimeUs < 0 ? mSeekTimeUs : videoTimeUs);
156182a2dd8efe48d3a4e04655f01329da857ace4b7dAdam Lesinski        mWatchForAudioSeekComplete = true;
1562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWatchForAudioEOS = true;
1563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else if (!mSeekNotificationSent) {
1564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // If we're playing video only, report seek complete now,
1565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // otherwise audio player will notify us later.
1566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        notifyListener_l(MEDIA_SEEK_COMPLETE);
1567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSeekNotificationSent = true;
1568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1570de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    modifyFlags(FIRST_FRAME, SET);
1571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeeking = NO_SEEK;
1572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mDecryptHandle != NULL) {
1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Playback::PAUSE, 0);
1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Playback::START, videoTimeUs / 1000);
1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1581de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinskivoid AwesomePlayer::onVideoEvent() {
1582de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    ATRACE_CALL();
1583de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    Mutex::Autolock autoLock(mLock);
1584de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    if (!mVideoEventPending) {
1585de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        // The event has been cancelled in reset_l() but had already
1586de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        // been scheduled for execution at that time.
1587de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        return;
1588fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
1589fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    mVideoEventPending = false;
1590fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1591fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (mSeeking != NO_SEEK) {
1592fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (mVideoBuffer) {
1593fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            mVideoBuffer->release();
159427f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski            mVideoBuffer = NULL;
159527f69f4e06961fdecd1078b2292d764a157e5e1cAdam Lesinski        }
1596fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1597fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        if (mSeeking == SEEK && isStreamingHTTP() && mAudioSource != NULL
1598fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                && !(mFlags & SEEK_PREVIEW)) {
1599fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            // We're going to seek the video source first, followed by
1600fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            // the audio source.
1601fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            // In order to avoid jumps in the DataSource offset caused by
1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // the audio codec prefetching data from the old locations
1603fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            // while the video codec is already reading data from the new
1604fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            // locations, we'll "pause" the audio source, causing it to
1605f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski            // stop reading input data until a subsequent seek.
1606f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski
1607f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski            if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
1608f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski                mAudioPlayer->pause();
1609f90f2f8dc36e7243b85e0b6a7fd5a590893c827eAdam Lesinski
1610fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                modifyFlags(AUDIO_RUNNING, CLEAR);
1611de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            }
1612de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            mAudioSource->pause();
1613de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        }
1614de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    }
1615fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1616fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    if (!mVideoBuffer) {
1617fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        MediaSource::ReadOptions options;
1618de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        if (mSeeking != NO_SEEK) {
1619de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            ALOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
1620de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1621de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            options.setSeekTo(
1622de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    mSeekTimeUs,
1623de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    mSeeking == SEEK_VIDEO_ONLY
1624de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
1625de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
1626de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        }
1627de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski        for (;;) {
1628de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            status_t err = mVideoSource->read(&mVideoBuffer, &options);
1629de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            options.clearSeekTo();
1630de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1631de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            if (err != OK) {
1632de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                CHECK(mVideoBuffer == NULL);
1633de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1634de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                if (err == INFO_FORMAT_CHANGED) {
1635de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    ALOGV("VideoSource signalled format change.");
1636de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1637de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    notifyVideoSize_l();
1638de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1639de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    if (mVideoRenderer != NULL) {
1640de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                        mVideoRendererIsPreview = false;
1641de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                        initRenderer_l();
1642de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    }
1643de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    continue;
1644de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                }
1645de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1646de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                // So video playback is complete, but we may still have
1647de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                // a seek request pending that needs to be applied
1648de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                // to the audio track.
1649de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                if (mSeeking != NO_SEEK) {
1650de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    ALOGV("video stream ended while seeking!");
1651de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                }
1652de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                finishSeekIfNecessary(-1);
1653de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1654de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                if (mAudioPlayer != NULL
1655de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                        && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1656de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                    startAudioPlayer_l();
1657de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                }
1658de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1659de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                modifyFlags(VIDEO_AT_EOS, SET);
1660de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                postStreamDoneEvent_l(err);
1661de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                return;
1662de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            }
1663de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1664de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski            if (mVideoBuffer->range_length() == 0) {
1665de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                // Some decoders, notably the PV AVC software decoder
1666de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski                // return spurious empty buffers that we just want to ignore.
1667de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
1668fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                mVideoBuffer->release();
1669fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski                mVideoBuffer = NULL;
16702cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey                continue;
16712cfc8482267707a671cbe4275ea8927c1aef991aJeff Sharkey            }
1672fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1673fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            break;
1674fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        }
1675fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1676fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        {
1677fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            Mutex::Autolock autoLock(mStatsLock);
1678fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski            ++mStats.mNumVideoFramesDecoded;
1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t timeUs;
1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mLastVideoTimeUs = timeUs;
1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mSeeking == SEEK_VIDEO_ONLY) {
1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mSeekTimeUs > timeUs) {
1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                 mSeekTimeUs, timeUs);
1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1694fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    {
1695fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        Mutex::Autolock autoLock(mMiscStateLock);
1696fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski        mVideoTimeUs = timeUs;
1697fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    }
1698fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski
1699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    SeekType wasSeeking = mSeeking;
1700fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski    finishSeekIfNecessary(timeUs);
1701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
1703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = startAudioPlayer_l();
1704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != OK) {
1705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGE("Starting the audio player failed w/ err %d", err);
1706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
1707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1708e572c011feabf6319ba836cf5bc4c3baa0ba6a85Adam Lesinski    }
1709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mFlags & TEXTPLAYER_INITIALIZED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
1711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTextDriver->start();
1712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(TEXT_RUNNING, SET);
1713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    TimeSource *ts =
1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ? &mSystemTimeSource : mTimeSource;
1718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & FIRST_FRAME) {
1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(FIRST_FRAME, CLEAR);
1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSinceLastDropped = 0;
1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t realTimeUs, mediaTimeUs;
1726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
1727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        && mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
1728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
1729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1730d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1731d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    if (wasSeeking == SEEK_VIDEO_ONLY) {
1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t latenessUs = nowUs - timeUs;
1735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ATRACE_INT("Video Lateness (ms)", latenessUs / 1E3);
1737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (latenessUs > 0) {
1739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
1740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (wasSeeking == NO_SEEK) {
1744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // Let's display the first frame after seeking right away.
1745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
1747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int64_t latenessUs = nowUs - timeUs;
1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ATRACE_INT("Video Lateness (ms)", latenessUs / 1E3);
1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (latenessUs > 500000ll
1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && mAudioPlayer != NULL
1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                && mAudioPlayer->getMediaTimeMapping(
1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    &realTimeUs, &mediaTimeUs)) {
1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("we're much too late (%.2f secs), video skipping ahead",
1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                 latenessUs / 1E6);
1758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mVideoBuffer->release();
1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mVideoBuffer = NULL;
1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSeeking = SEEK_VIDEO_ONLY;
1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSeekTimeUs = mediaTimeUs;
1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            postVideoEvent_l();
1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (latenessUs > 40000) {
1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // We're more than 40ms late.
1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGV("we're late by %lld us (%.2f secs)",
1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                 latenessUs, latenessUs / 1E6);
1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (!(mFlags & SLOW_DECODER_HACK)
1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    || mSinceLastDropped > FRAME_DROP_FREQ)
1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            {
1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                ALOGV("we're late by %lld us (%.2f secs) dropping "
1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                     "one after %d frames",
1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                     latenessUs, latenessUs / 1E6, mSinceLastDropped);
1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mSinceLastDropped = 0;
1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mVideoBuffer->release();
1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mVideoBuffer = NULL;
1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                {
1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    Mutex::Autolock autoLock(mStatsLock);
1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    ++mStats.mNumVideoFramesDropped;
1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                postVideoEvent_l();
1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return;
1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17954bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski        if (latenessUs < -10000) {
1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // We're more than 10ms early.
1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            postVideoEvent_l(10000);
1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mNativeWindow != NULL)
1803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            && (mVideoRendererIsPreview || mVideoRenderer == NULL)) {
1804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mVideoRendererIsPreview = false;
1805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        initRenderer_l();
1807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoRenderer != NULL) {
1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSinceLastDropped++;
1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mVideoRenderer->render(mVideoBuffer);
1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!mVideoRenderingStarted) {
1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mVideoRenderingStarted = true;
1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyListener_l(MEDIA_INFO, MEDIA_INFO_RENDERING_START);
1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoBuffer->release();
1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoBuffer = NULL;
1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(SEEK_PREVIEW, CLEAR);
1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    postVideoEvent_l();
1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
1831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoEventPending) {
1834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoEventPending = true;
18384bf58108d442b37ab4adf5ce3a4ecd63472ce254Adam Lesinski    mQueue.postEventWithDelay(mVideoEvent, delayUs < 0 ? 10000 : delayUs);
1839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postStreamDoneEvent_l(status_t status) {
1842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mStreamDoneEventPending) {
1843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mStreamDoneEventPending = true;
1846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mStreamDoneStatus = status;
1848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mQueue.postEvent(mStreamDoneEvent);
1849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postBufferingEvent_l() {
1852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mBufferingEventPending) {
1853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mBufferingEventPending = true;
1856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
1857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postVideoLagEvent_l() {
1860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoLagEventPending) {
1861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoLagEventPending = true;
1864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
1865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postCheckAudioStatusEvent(int64_t delayUs) {
1868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mAudioLock);
1869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioStatusEventPending) {
1870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
1871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioStatusEventPending = true;
1873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Do not honor delay when looping in order to limit audio gap
1874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & (LOOPING | AUTO_LOOPING)) {
1875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delayUs = 0;
1876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
1878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::onCheckAudioStatus() {
1881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
1882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mAudioLock);
1883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!mAudioStatusEventPending) {
1884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // Event was dispatched and while we were blocking on the mutex,
1885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // has already been cancelled.
1886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
1887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAudioStatusEventPending = false;
1890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
1893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
1895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWatchForAudioSeekComplete = false;
1896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!mSeekNotificationSent) {
1898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyListener_l(MEDIA_SEEK_COMPLETE);
1899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mSeekNotificationSent = true;
1900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
1901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mSeeking = NO_SEEK;
1903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t finalStatus;
1906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mWatchForAudioEOS && mAudioPlayer->reachedEOS(&finalStatus)) {
1907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWatchForAudioEOS = false;
1908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(AUDIO_AT_EOS, SET);
1909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        modifyFlags(FIRST_FRAME, SET);
1910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        postStreamDoneEvent_l(finalStatus);
1911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::prepare() {
1915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
1917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return prepare_l();
1918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::prepare_l() {
1921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & PREPARED) {
1922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OK;
1923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & PREPARING) {
1926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return UNKNOWN_ERROR;
1927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mIsAsyncPrepare = false;
1930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = prepareAsync_l();
1931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != OK) {
1933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
1934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (mFlags & PREPARING) {
1937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mPreparedCondition.wait(mLock);
1938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return mPrepareResult;
1941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1942d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1943d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinskistatus_t AwesomePlayer::prepareAsync() {
1944d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    ATRACE_CALL();
1945d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    Mutex::Autolock autoLock(mLock);
1946d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1947d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    if (mFlags & PREPARING) {
1948d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski        return UNKNOWN_ERROR;  // async prepare already pending
1949d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    }
1950d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1951d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    mIsAsyncPrepare = true;
1952d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    return prepareAsync_l();
1953d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski}
1954d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1955d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinskistatus_t AwesomePlayer::prepareAsync_l() {
1956d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    if (mFlags & PREPARING) {
1957d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski        return UNKNOWN_ERROR;  // async prepare already pending
1958d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    }
1959d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1960d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    if (!mQueueStarted) {
1961d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski        mQueue.start();
1962d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski        mQueueStarted = true;
1963d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    }
1964d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1965d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    modifyFlags(PREPARING, SET);
1966d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    mAsyncPrepareEvent = new AwesomeEvent(
1967d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski            this, &AwesomePlayer::onPrepareAsyncEvent);
1968d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1969d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski    mQueue.postEvent(mAsyncPrepareEvent);
1970d3edfde51bd069a63e820282421d1a534fcf00ceAdam Lesinski
1971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
1972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
1973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::finishSetDataSource_l() {
1975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
1976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<DataSource> dataSource;
1977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool isWidevineStreaming = false;
1979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!strncasecmp("widevine://", mUri.string(), 11)) {
1980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        isWidevineStreaming = true;
1981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 newURI = String8("http://");
1983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        newURI.append(mUri.string() + 11);
1984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mUri = newURI;
1986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
1987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AString sniffedMIME;
1989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (!strncasecmp("http://", mUri.string(), 7)
1991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            || !strncasecmp("https://", mUri.string(), 8)
1992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            || isWidevineStreaming) {
1993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mConnectingDataSource = HTTPBase::Create(
1994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                (mFlags & INCOGNITO)
1995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    ? HTTPBase::kFlagIncognito
1996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    : 0);
1997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mUIDValid) {
1999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mConnectingDataSource->setUID(mUID);
2000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 cacheConfig;
2003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bool disconnectAtHighwatermark;
2004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        NuCachedSource2::RemoveCacheSpecificHeaders(
2005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
2006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLock.unlock();
2008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
2009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLock.lock();
2010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != OK) {
2012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mConnectingDataSource.clear();
2013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("mConnectingDataSource->connect() returned %d", err);
2015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return err;
2016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!isWidevineStreaming) {
2019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // The widevine extractor does its own caching.
2020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0
2022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mCachedSource = new NuCachedSource2(
2023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    new ThrottledSource(
2024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        mConnectingDataSource, 50 * 1024 /* bytes/sec */));
2025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else
2026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mCachedSource = new NuCachedSource2(
2027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mConnectingDataSource,
2028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
2029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    disconnectAtHighwatermark);
2030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif
2031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            dataSource = mCachedSource;
2033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
2034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            dataSource = mConnectingDataSource;
2035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mConnectingDataSource.clear();
2038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 contentType = dataSource->getMIMEType();
2040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (strncasecmp(contentType.string(), "audio/", 6)) {
2042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // We're not doing this for streams that appear to be audio-only
2043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // streams to ensure that even low bandwidth streams start
2044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // playing back fairly instantly.
2045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // We're going to prefill the cache before trying to instantiate
2047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // the extractor below, as the latter is an operation that otherwise
2048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // could block on the datasource for a significant amount of time.
2049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // During that time we'd be unable to abort the preparation phase
2050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // without this prefill.
2051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mCachedSource != NULL) {
2052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // We're going to prefill the cache before trying to instantiate
20530f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                // the extractor below, as the latter is an operation that otherwise
20540f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                // could block on the datasource for a significant amount of time.
20550f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                // During that time we'd be unable to abort the preparation phase
2056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // without this prefill.
2057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLock.unlock();
2059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
20600f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                // Initially make sure we have at least 192 KB for the sniff
2061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // to complete without blocking.
2062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                static const size_t kMinBytesForSniffing = 192 * 1024;
2063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                off64_t metaDataSize = -1ll;
2065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                for (;;) {
2066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    status_t finalStatus;
2067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    size_t cachedDataRemaining =
2068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        mCachedSource->approxDataRemaining(&finalStatus);
2069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
20700f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                    if (finalStatus != OK
20710f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                            || (metaDataSize >= 0
20720f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                                && cachedDataRemaining >= metaDataSize)
20730f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                            || (mFlags & PREPARE_CANCELLED)) {
20740f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        break;
20750f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                    }
20760f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba
20770f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                    ALOGV("now cached %d bytes of data", cachedDataRemaining);
20780f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba
2079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (metaDataSize < 0
2080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            && cachedDataRemaining >= kMinBytesForSniffing) {
2081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        String8 tmp;
20820f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        float confidence;
20830f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        sp<AMessage> meta;
20840f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        if (!dataSource->sniff(&tmp, &confidence, &meta)) {
2085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            mLock.lock();
2086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            return UNKNOWN_ERROR;
2087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        }
2088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // We successfully identified the file's extractor to
2090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // be, remember this mime type so we don't have to
2091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // sniff it again when we call MediaExtractor::Create()
20920f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        // below.
2093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        sniffedMIME = tmp.string();
2094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        if (meta == NULL
2096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                || !meta->findInt64(
2097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                    "meta-data-size", &metaDataSize)) {
20980f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                            metaDataSize = kHighWaterMarkBytes;
20990f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        }
21000f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba
21010f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        CHECK_GE(metaDataSize, 0ll);
21020f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                        ALOGV("metaDataSize = %lld bytes", metaDataSize);
2103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
2104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    usleep(200000);
2106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
2107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mLock.lock();
2109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
21100f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba
21110f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba            if (mFlags & PREPARE_CANCELLED) {
21120f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                ALOGI("Prepare cancelled while waiting for initial cache fill.");
21130f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba                return UNKNOWN_ERROR;
21140f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba            }
21150f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba        }
21160f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba    } else {
21170f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba        dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
21181e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski    }
21191e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski
21200f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba    if (dataSource == NULL) {
21210f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba        return UNKNOWN_ERROR;
21221e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski    }
21231e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski
2124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    sp<MediaExtractor> extractor;
2125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2126e8e91925074479fc06310418b58b54f49d051801Adam Lesinski    if (isWidevineStreaming) {
2127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 mimeType;
2128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        float confidence;
2129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<AMessage> dummy;
2130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bool success;
2131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // SniffWVM is potentially blocking since it may require network access.
2133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // Do not call it with mLock held.
2134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLock.unlock();
2135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
2136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mLock.lock();
2137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!success
2139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                || strcasecmp(
2140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
2141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return ERROR_UNSUPPORTED;
2142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWVMExtractor = new WVMExtractor(dataSource);
2145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWVMExtractor->setAdaptiveStreamingMode(true);
2146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mUIDValid)
2147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mWVMExtractor->setUID(mUID);
2148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        extractor = mWVMExtractor;
2149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
2150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        extractor = MediaExtractor::Create(
2151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());
2152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (extractor == NULL) {
2154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return UNKNOWN_ERROR;
2155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (extractor->getDrmFlag()) {
2159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        checkDrmStatus(dataSource);
2160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = setDataSource_l(extractor);
2163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (err != OK) {
2165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mWVMExtractor.clear();
2166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
2168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
2171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::abortPrepare(status_t err) {
2174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(err != OK);
2175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mIsAsyncPrepare) {
2177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
2178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mPrepareResult = err;
2181eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
2182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAsyncPrepareEvent = NULL;
2183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mPreparedCondition.broadcast();
2184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2185eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown
2186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// static
2187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool AwesomePlayer::ContinuePreparation(void *cookie) {
2188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    AwesomePlayer *me = static_cast<AwesomePlayer *>(cookie);
2189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return (me->mFlags & PREPARE_CANCELLED) == 0;
2191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::onPrepareAsyncEvent() {
2194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
2195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mFlags & PREPARE_CANCELLED) {
2197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGI("prepare was cancelled before doing anything");
2198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        abortPrepare(UNKNOWN_ERROR);
2199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return;
2200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mUri.size() > 0) {
2203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = finishSetDataSource_l();
2204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != OK) {
2206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            abortPrepare(err);
2207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
2208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mVideoTrack != NULL && mVideoSource == NULL) {
2212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = initVideoDecoder();
2213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != OK) {
2215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            abortPrepare(err);
2216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
2217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mAudioTrack != NULL && mAudioSource == NULL) {
2221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = initAudioDecoder();
2222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err != OK) {
2224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            abortPrepare(err);
2225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
2226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(PREPARING_CONNECTED, SET);
2230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (isStreamingHTTP()) {
2232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        postBufferingEvent_l();
2233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
2234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        finishAsyncPrepare_l();
2235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::finishAsyncPrepare_l() {
2239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mIsAsyncPrepare) {
2240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mVideoSource == NULL) {
2241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0);
2242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
2243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            notifyVideoSize_l();
2244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        notifyListener_l(MEDIA_PREPARED);
2247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mPrepareResult = OK;
2250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR);
2251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(PREPARED, SET);
2252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAsyncPrepareEvent = NULL;
2253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mPreparedCondition.broadcast();
2254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiuint32_t AwesomePlayer::flags() const {
2257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return mExtractorFlags;
2258eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown}
2259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postAudioEOS(int64_t delayUs) {
2261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    postCheckAudioStatusEvent(delayUs);
2262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid AwesomePlayer::postAudioSeekComplete() {
2265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    postCheckAudioStatusEvent(0);
2266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setParameter(int key, const Parcel &request) {
2269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch (key) {
2270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
2271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return setCacheStatCollectFreq(request);
2273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case KEY_PARAMETER_PLAYBACK_RATE_PERMILLE:
2275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mAudioPlayer != NULL) {
2277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return mAudioPlayer->setPlaybackRatePermille(request.readInt32());
2278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } else {
2279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return NO_INIT;
2280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
2281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        default:
2283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return ERROR_UNSUPPORTED;
2285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setCacheStatCollectFreq(const Parcel &request) {
2290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mCachedSource != NULL) {
2291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int32_t freqMs = request.readInt32();
2292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGD("Request to keep cache stats in the past %d ms",
2293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            freqMs);
2294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mCachedSource->setCacheStatCollectFreq(freqMs);
2295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return ERROR_UNSUPPORTED;
2297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::getParameter(int key, Parcel *reply) {
2300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch (key) {
2301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
2302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int32_t channelCount;
2304eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown            if (mAudioTrack == 0 ||
2305eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown                    !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
2306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                channelCount = 0;
2307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
2308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            reply->writeInt32(channelCount);
2309eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown        }
2310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return OK;
2311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    default:
2312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return ERROR_UNSUPPORTED;
2314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::getTrackInfo(Parcel *reply) const {
2319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
2320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    size_t trackCount = mExtractor->countTracks();
2321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mTextDriver != NULL) {
2322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        trackCount += mTextDriver->countExternalTracks();
2323eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    }
2324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    reply->writeInt32(trackCount);
2326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
2327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MetaData> meta = mExtractor->getTrackMetaData(i);
2328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const char *_mime;
2330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        CHECK(meta->findCString(kKeyMIMEType, &_mime));
2331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String8 mime = String8(_mime);
2333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        reply->writeInt32(2); // 2 fields
2335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!strncasecmp(mime.string(), "video/", 6)) {
2337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            reply->writeInt32(MEDIA_TRACK_TYPE_VIDEO);
2338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (!strncasecmp(mime.string(), "audio/", 6)) {
2339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            reply->writeInt32(MEDIA_TRACK_TYPE_AUDIO);
2340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else if (!strcasecmp(mime.string(), MEDIA_MIMETYPE_TEXT_3GPP)) {
2341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            reply->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
2342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
2343eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown            reply->writeInt32(MEDIA_TRACK_TYPE_UNKNOWN);
2344e8e91925074479fc06310418b58b54f49d051801Adam Lesinski        }
2345e8e91925074479fc06310418b58b54f49d051801Adam Lesinski
2346e8e91925074479fc06310418b58b54f49d051801Adam Lesinski        const char *lang;
2347e8e91925074479fc06310418b58b54f49d051801Adam Lesinski        if (!meta->findCString(kKeyMediaLanguage, &lang)) {
2348e8e91925074479fc06310418b58b54f49d051801Adam Lesinski            lang = "und";
2349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2350e8e91925074479fc06310418b58b54f49d051801Adam Lesinski        reply->writeString16(String16(lang));
2351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mTextDriver != NULL) {
2354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mTextDriver->getExternalTrackInfo(reply);
2355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
2357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::selectAudioTrack_l(
2360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const sp<MediaSource>& source, size_t trackIndex) {
2361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGI("selectAudioTrack_l: trackIndex=%d, mFlags=0x%x", trackIndex, mFlags);
2363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
2365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
2366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if ((ssize_t)trackIndex == mActiveAudioTrackIndex) {
2367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGI("Track %d is active. Does nothing.", trackIndex);
2368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return OK;
2369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        //mStats.mFlags = mFlags;
2371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mSeeking != NO_SEEK) {
2374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGE("Selecting a track while seeking is not supported");
2375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return ERROR_UNSUPPORTED;
2376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mFlags & PREPARED) == 0) {
2379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGE("Data source has not finished preparation");
2380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return ERROR_UNSUPPORTED;
2381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK(source != NULL);
2384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool wasPlaying = (mFlags & PLAYING) != 0;
2385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    pause_l();
2387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int64_t curTimeUs;
2389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    CHECK_EQ(getPosition(&curTimeUs), (status_t)OK);
2390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
2392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            && mAudioSource != NULL) {
2393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // If we had an audio player, it would have effectively
2394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // taken possession of the audio source and stopped it when
2395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // _it_ is stopped. Otherwise this is still our responsibility.
2396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mAudioSource->stop();
2397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioSource.clear();
2399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mTimeSource = NULL;
2401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    delete mAudioPlayer;
2403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mAudioPlayer = NULL;
2404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(AUDIOPLAYER_STARTED, CLEAR);
2406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    setAudioSource(source);
2408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(AUDIO_AT_EOS, CLEAR);
2410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    modifyFlags(AT_EOS, CLEAR);
2411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err;
2413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ((err = initAudioDecoder()) != OK) {
2414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGE("Failed to init audio decoder: 0x%x", err);
2415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return err;
2416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mSeekNotificationSent = true;
2419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    seekTo_l(curTimeUs);
2420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (wasPlaying) {
2422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        play_l();
2423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mActiveAudioTrackIndex = trackIndex;
2426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
2428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
2431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
2432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ALOGV("selectTrack: trackIndex = %d and select=%d", trackIndex, select);
2433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock autoLock(mLock);
2434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    size_t trackCount = mExtractor->countTracks();
2435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mTextDriver != NULL) {
2436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        trackCount += mTextDriver->countExternalTracks();
2437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (trackIndex >= trackCount) {
2439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ALOGE("Track index (%d) is out of range [0, %d)", trackIndex, trackCount);
2440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return ERROR_OUT_OF_RANGE;
2441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool isAudioTrack = false;
2444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (trackIndex < mExtractor->countTracks()) {
2445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sp<MetaData> meta = mExtractor->getTrackMetaData(trackIndex);
2446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const char *mime;
2447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        CHECK(meta->findCString(kKeyMIMEType, &mime));
2448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        isAudioTrack = !strncasecmp(mime, "audio/", 6);
2449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!isAudioTrack && strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) != 0) {
2451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGE("Track %d is not either audio or timed text", trackIndex);
2452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return ERROR_UNSUPPORTED;
2453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (isAudioTrack) {
2457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!select) {
2458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGE("Deselect an audio track (%d) is not supported", trackIndex);
2459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return ERROR_UNSUPPORTED;
2460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
24611e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski        return selectAudioTrack_l(mExtractor->getTrack(trackIndex), trackIndex);
2462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // Timed text track handling
2465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mTextDriver == NULL) {
2466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return INVALID_OPERATION;
2467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    status_t err = OK;
2470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (select) {
2471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = mTextDriver->selectTrack(trackIndex);
2472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err == OK) {
2473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            modifyFlags(TEXTPLAYER_INITIALIZED, SET);
2474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mFlags & PLAYING && !(mFlags & TEXT_RUNNING)) {
2475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mTextDriver->start();
2476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                modifyFlags(TEXT_RUNNING, SET);
2477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
2478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
2480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        err = mTextDriver->unselectTrack(trackIndex);
2481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (err == OK) {
2482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            modifyFlags(TEXTPLAYER_INITIALIZED, CLEAR);
2483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            modifyFlags(TEXT_RUNNING, CLEAR);
2484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return err;
2487eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown}
2488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskisize_t AwesomePlayer::countTracks() const {
2490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return mExtractor->countTracks() + mTextDriver->countExternalTracks();
2491eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown}
2492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setVideoScalingMode(int32_t mode) {
2494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex::Autolock lock(mLock);
2495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return setVideoScalingMode_l(mode);
2496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::setVideoScalingMode_l(int32_t mode) {
2499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mVideoScalingMode = mode;
2500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mNativeWindow != NULL) {
2501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        status_t err = native_window_set_scaling_mode(
2502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mNativeWindow.get(), mVideoScalingMode);
2503eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown        if (err != OK) {
2504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ALOGW("Failed to set scaling mode: %d", err);
2505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
2508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t AwesomePlayer::invoke(const Parcel &request, Parcel *reply) {
2511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ATRACE_CALL();
2512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (NULL == reply) {
2513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return android::BAD_VALUE;
2514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int32_t methodId;
2516eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown    status_t ret = request.readInt32(&methodId);
2517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (ret != android::OK) {
2518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return ret;
2519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch(methodId) {
2521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case INVOKE_ID_SET_VIDEO_SCALING_MODE:
2522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int mode = request.readInt32();
2524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return setVideoScalingMode(mode);
2525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case INVOKE_ID_GET_TRACK_INFO:
2528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return getTrackInfo(reply);
2530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case INVOKE_ID_ADD_EXTERNAL_SOURCE:
2532eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown        {
2533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Mutex::Autolock autoLock(mLock);
2534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mTextDriver == NULL) {
2535eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown                mTextDriver = new TimedTextDriver(mListener);
2536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
2537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // String values written in Parcel are UTF-16 values.
2538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String8 uri(request.readString16());
2539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String8 mimeType(request.readString16());
2540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            size_t nTracks = countTracks();
2541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return mTextDriver->addOutOfBandTextSource(nTracks, uri, mimeType);
2542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case INVOKE_ID_ADD_EXTERNAL_SOURCE_FD:
2544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Mutex::Autolock autoLock(mLock);
2546eb490d6194bd79adbe144a1230fc126f4c180a2fJeff Brown            if (mTextDriver == NULL) {
2547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                mTextDriver = new TimedTextDriver(mListener);
2548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
2549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int fd         = request.readFileDescriptor();
2550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            off64_t offset = request.readInt64();
2551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            off64_t length  = request.readInt64();
2552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String8 mimeType(request.readString16());
2553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            size_t nTracks = countTracks();
2554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return mTextDriver->addOutOfBandTextSource(
2555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    nTracks, fd, offset, length, mimeType);
2556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case INVOKE_ID_SELECT_TRACK:
2558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int trackIndex = request.readInt32();
2560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return selectTrack(trackIndex, true /* select */);
25611e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski        }
25621e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski        case INVOKE_ID_UNSELECT_TRACK:
2563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int trackIndex = request.readInt32();
2565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return selectTrack(trackIndex, false /* select */);
2566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        default:
2568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
2569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return ERROR_UNSUPPORTED;
2570e8e91925074479fc06310418b58b54f49d051801Adam Lesinski        }
2571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // It will not reach here.
2573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
2574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
25761e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinskibool AwesomePlayer::isStreamingHTTP() const {
25770f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba    return mCachedSource != NULL || mWVMExtractor != NULL;
25780f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba}
25790f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosiba
25800f3a5a6559a955ea20f1ae2d3e0995f3fa821c90Marcin Kosibastatus_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
25811e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski    Mutex::Autolock autoLock(mStatsLock);
25821e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinski
2583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FILE *out = fdopen(dup(fd), "w");
2584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(out, " AwesomePlayer\n");
2586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mStats.mFd < 0) {
2587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(out, "  URI(suppressed)");
2588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
2589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(out, "  fd(%d)", mStats.mFd);
2590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(out, ", flags(0x%08x)", mStats.mFlags);
2593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (mStats.mBitrate >= 0) {
2595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate);
2596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fprintf(out, "\n");
2599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
2601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const TrackStat &stat = mStats.mTracks.itemAt(i);
2602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(out, "  Track %d\n", i + 1);
2604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(out, "   MIME(%s)", stat.mMIME.string());
2605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!stat.mDecoderName.isEmpty()) {
2607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(out, ", decoder(%s)", stat.mDecoderName.string());
2608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        fprintf(out, "\n");
2611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if ((ssize_t)i == mStats.mVideoTrackIndex) {
2613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            fprintf(out,
2614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "   videoDimensions(%d x %d), "
2615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "numVideoFramesDecoded(%lld), "
2616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "numVideoFramesDropped(%lld)\n",
2617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mStats.mVideoWidth,
2618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mStats.mVideoHeight,
2619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mStats.mNumVideoFramesDecoded,
2620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mStats.mNumVideoFramesDropped);
2621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
2622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    fclose(out);
2625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    out = NULL;
2626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return OK;
2628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
26301e466385d4a4f1acee080fa0fdf16cc8fd8ce7caAdam Lesinskivoid AwesomePlayer::modifyFlags(unsigned value, FlagMode mode) {
2631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    switch (mode) {
2632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case SET:
2633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mFlags |= value;
2634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            break;
2635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case CLEAR:
2636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if ((value & CACHE_UNDERRUN) && (mFlags & CACHE_UNDERRUN)) {
2637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
2638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
2639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mFlags &= ~value;
2640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            break;
2641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        case ASSIGN:
2642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mFlags = value;
2643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            break;
2644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        default:
2645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            TRESPASS();
2646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
2649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Autolock autoLock(mStatsLock);
2650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mStats.mFlags = mFlags;
2651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
2652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
2653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
2654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}  // namespace android
2655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski