NuPlayer.cpp revision f3b5190f2aa659d498b1d31389b90a441fc879a7
1eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/*
2eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * Copyright (C) 2010 The Android Open Source Project
3eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov *
4eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * Licensed under the Apache License, Version 2.0 (the "License");
5eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * you may not use this file except in compliance with the License.
6eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * You may obtain a copy of the License at
7eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov *
8eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov *      http://www.apache.org/licenses/LICENSE-2.0
9eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov *
10eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * Unless required by applicable law or agreed to in writing, software
11eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * distributed under the License is distributed on an "AS IS" BASIS,
12eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * See the License for the specific language governing permissions and
14eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov * limitations under the License.
15eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov */
16eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
17eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov//#define LOG_NDEBUG 0
18eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#define LOG_TAG "NuPlayer"
19eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <utils/Log.h>
20eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
21eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "NuPlayer.h"
22eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
23eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "HTTPLiveSource.h"
24eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "NuPlayerDecoder.h"
25eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "NuPlayerDecoderPassThrough.h"
26eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "NuPlayerDriver.h"
27eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "NuPlayerRenderer.h"
28eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "NuPlayerSource.h"
29eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "RTSPSource.h"
30eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "StreamingSource.h"
31eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "GenericSource.h"
32eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "TextDescriptions.h"
33eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
34eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "ATSParser.h"
35eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
36eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/foundation/hexdump.h>
37eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/foundation/ABuffer.h>
38eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/foundation/ADebug.h>
39eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/foundation/AMessage.h>
40eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/MediaBuffer.h>
41eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/MediaDefs.h>
42eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/MediaErrors.h>
43eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/MetaData.h>
44eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <gui/IGraphicBufferProducer.h>
45eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
46eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "avc_utils.h"
47eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
48eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "ESDS.h"
49eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include <media/stagefright/Utils.h>
50eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
51eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovnamespace android {
52eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
53eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstruct NuPlayer::Action : public RefBase {
54eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    Action() {}
55eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
56eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    virtual void execute(NuPlayer *player) = 0;
57eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
58eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovprivate:
59eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    DISALLOW_EVIL_CONSTRUCTORS(Action);
60eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov};
61eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
62eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstruct NuPlayer::SeekAction : public Action {
63eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    SeekAction(int64_t seekTimeUs)
64eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        : mSeekTimeUs(seekTimeUs) {
65eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
66eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
67eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    virtual void execute(NuPlayer *player) {
68eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        player->performSeek(mSeekTimeUs);
69eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
70eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
71eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovprivate:
72eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    int64_t mSeekTimeUs;
73eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
74eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
75eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov};
76eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
77eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstruct NuPlayer::SetSurfaceAction : public Action {
78eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
79eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        : mWrapper(wrapper) {
80eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
81eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
82eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    virtual void execute(NuPlayer *player) {
83eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        player->performSetSurface(mWrapper);
84eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
85eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
86eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovprivate:
87eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<NativeWindowWrapper> mWrapper;
88eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
89eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
90eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov};
91eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
92eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstruct NuPlayer::ShutdownDecoderAction : public Action {
93eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    ShutdownDecoderAction(bool audio, bool video)
94eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        : mAudio(audio),
95eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov          mVideo(video) {
96eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
97eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
98eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    virtual void execute(NuPlayer *player) {
99eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        player->performDecoderShutdown(mAudio, mVideo);
100eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
101eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
102eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovprivate:
103eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    bool mAudio;
104eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    bool mVideo;
105eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
106eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction);
107eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov};
108eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
109eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstruct NuPlayer::PostMessageAction : public Action {
110eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    PostMessageAction(const sp<AMessage> &msg)
111eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        : mMessage(msg) {
112eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
113eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
114eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    virtual void execute(NuPlayer *) {
115eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        mMessage->post();
116eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
117eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
118eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovprivate:
119eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> mMessage;
120eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
121eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
122eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov};
123eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
124eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov// Use this if there's no state necessary to save in order to execute
125eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov// the action.
126eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstruct NuPlayer::SimpleAction : public Action {
127eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    typedef void (NuPlayer::*ActionFunc)();
128eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
129eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    SimpleAction(ActionFunc func)
130eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        : mFunc(func) {
131eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
132eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
133eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    virtual void execute(NuPlayer *player) {
134eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        (player->*mFunc)();
135eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
136eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
137eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovprivate:
138eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    ActionFunc mFunc;
139eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
140eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
141eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov};
142eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
143eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov////////////////////////////////////////////////////////////////////////////////
144eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
145eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy IvanovNuPlayer::NuPlayer()
146eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    : mUIDValid(false),
147eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mSourceFlags(0),
148eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mCurrentPositionUs(0),
149eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mVideoIsAVC(false),
150eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mOffloadAudio(false),
151eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
152eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mAudioDecoderGeneration(0),
153eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mVideoDecoderGeneration(0),
154eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mAudioEOS(false),
155eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mVideoEOS(false),
156eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mScanSourcesPending(false),
157eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mScanSourcesGeneration(0),
158eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mPollDurationGeneration(0),
159eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mTimedTextGeneration(0),
160eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mTimeDiscontinuityPending(false),
161eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mFlushingAudio(NONE),
162eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mFlushingVideo(NONE),
163eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
164eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
165eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mVideoLateByUs(0ll),
166eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mNumFramesTotal(0ll),
167eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mNumFramesDropped(0ll),
168eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
169eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      mStarted(false) {
170eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
171eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
172eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy IvanovNuPlayer::~NuPlayer() {
173eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
174eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
175eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setUID(uid_t uid) {
176eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    mUIDValid = true;
177eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    mUID = uid;
178eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
179eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
180eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
181eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    mDriver = driver;
182eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
183eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
184eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
185eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
186eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
187eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
188eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
189eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->setObject("source", new StreamingSource(notify, source));
190eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->post();
191eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
192eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
193eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstatic bool IsHTTPLiveURL(const char *url) {
194eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    if (!strncasecmp("http://", url, 7)
195eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            || !strncasecmp("https://", url, 8)
196eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            || !strncasecmp("file://", url, 7)) {
197eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        size_t len = strlen(url);
198eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
199eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            return true;
200eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        }
201eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
202eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        if (strstr(url,"m3u8")) {
203eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            return true;
204eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        }
205eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
206eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
207eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    return false;
208eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
209eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
210eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setDataSourceAsync(
211eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        const sp<IMediaHTTPService> &httpService,
212eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        const char *url,
213eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        const KeyedVector<String8, String8> *headers) {
214eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
215eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
216eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    size_t len = strlen(url);
217eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
218eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
219eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
220eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<Source> source;
221eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    if (IsHTTPLiveURL(url)) {
222eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        source = new HTTPLiveSource(notify, httpService, url, headers);
223eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    } else if (!strncasecmp(url, "rtsp://", 7)) {
224eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        source = new RTSPSource(
225eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                notify, httpService, url, headers, mUIDValid, mUID);
226eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    } else if ((!strncasecmp(url, "http://", 7)
227eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                || !strncasecmp(url, "https://", 8))
228eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
229eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    || strstr(url, ".sdp?"))) {
230eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        source = new RTSPSource(
231eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                notify, httpService, url, headers, mUIDValid, mUID, true);
232eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    } else {
233eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        sp<GenericSource> genericSource =
234eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                new GenericSource(notify, mUIDValid, mUID);
235eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        // Don't set FLAG_SECURE on mSourceFlags here for widevine.
236eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        // The correct flags will be updated in Source::kWhatFlagsChanged
237eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        // handler when  GenericSource is prepared.
238eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
239eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        status_t err = genericSource->setDataSource(httpService, url, headers);
240eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
241eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        if (err == OK) {
242eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            source = genericSource;
243eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        } else {
244eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            ALOGE("Failed to set data source!");
245eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        }
246eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
247eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->setObject("source", source);
248eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->post();
249eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
250eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
251eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
252eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
253eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
254eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
255eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
256eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<GenericSource> source =
257eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            new GenericSource(notify, mUIDValid, mUID);
258eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
259eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    status_t err = source->setDataSource(fd, offset, length);
260eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
261eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    if (err != OK) {
262eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        ALOGE("Failed to set data source!");
263eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        source = NULL;
264eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
265eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
266eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->setObject("source", source);
267eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->post();
268eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
269eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
270eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::prepareAsync() {
271eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    (new AMessage(kWhatPrepare, id()))->post();
272eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
273eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
274eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setVideoSurfaceTextureAsync(
275eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        const sp<IGraphicBufferProducer> &bufferProducer) {
276eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, id());
277eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
278eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    if (bufferProducer == NULL) {
279eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        msg->setObject("native-window", NULL);
280eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    } else {
281eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        msg->setObject(
282eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                "native-window",
283eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                new NativeWindowWrapper(
284eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                    new Surface(bufferProducer, true /* controlledByApp */)));
285eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
286eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
287eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->post();
288eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
289eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
290eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
291eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, id());
292eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->setObject("sink", sink);
293eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->post();
294eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
295eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
296eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::start() {
297eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    (new AMessage(kWhatStart, id()))->post();
298eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
299eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
300eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::pause() {
301eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    (new AMessage(kWhatPause, id()))->post();
302eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
303eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
304eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::resume() {
305eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    (new AMessage(kWhatResume, id()))->post();
306eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
307eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
308eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::resetAsync() {
309eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    (new AMessage(kWhatReset, id()))->post();
310eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
311eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
312eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::seekToAsync(int64_t seekTimeUs) {
313eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    sp<AMessage> msg = new AMessage(kWhatSeek, id());
314eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->setInt64("seekTimeUs", seekTimeUs);
315eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    msg->post();
316eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
317eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
318eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov// static
319eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovbool NuPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
320eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    switch (state) {
321eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        case FLUSHING_DECODER:
322eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            if (needShutdown != NULL) {
323eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                *needShutdown = false;
324eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            }
325eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            return true;
326eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
327eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        case FLUSHING_DECODER_SHUTDOWN:
328eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            if (needShutdown != NULL) {
329eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                *needShutdown = true;
330eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            }
331eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            return true;
332eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
333eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        default:
334eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            return false;
335eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    }
336eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
337eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
338eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid NuPlayer::writeTrackInfo(
339eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        Parcel* reply, const sp<AMessage> format) const {
340eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    int32_t trackType;
341eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    CHECK(format->findInt32("type", &trackType));
342eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
343eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    AString lang;
344eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    CHECK(format->findString("language", &lang));
345eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
346eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    reply->writeInt32(2); // write something non-zero
347eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    reply->writeInt32(trackType);
348eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    reply->writeString16(String16(lang.c_str()));
349eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
350eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
351eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        AString mime;
352eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        CHECK(format->findString("mime", &mime));
353eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
354eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov        int32_t isAuto, isDefault, isForced;
355        CHECK(format->findInt32("auto", &isAuto));
356        CHECK(format->findInt32("default", &isDefault));
357        CHECK(format->findInt32("forced", &isForced));
358
359        reply->writeString16(String16(mime.c_str()));
360        reply->writeInt32(isAuto);
361        reply->writeInt32(isDefault);
362        reply->writeInt32(isForced);
363    }
364}
365
366void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
367    switch (msg->what()) {
368        case kWhatSetDataSource:
369        {
370            ALOGV("kWhatSetDataSource");
371
372            CHECK(mSource == NULL);
373
374            status_t err = OK;
375            sp<RefBase> obj;
376            CHECK(msg->findObject("source", &obj));
377            if (obj != NULL) {
378                mSource = static_cast<Source *>(obj.get());
379            } else {
380                err = UNKNOWN_ERROR;
381            }
382
383            CHECK(mDriver != NULL);
384            sp<NuPlayerDriver> driver = mDriver.promote();
385            if (driver != NULL) {
386                driver->notifySetDataSourceCompleted(err);
387            }
388            break;
389        }
390
391        case kWhatPrepare:
392        {
393            mSource->prepareAsync();
394            break;
395        }
396
397        case kWhatGetTrackInfo:
398        {
399            uint32_t replyID;
400            CHECK(msg->senderAwaitsResponse(&replyID));
401
402            Parcel* reply;
403            CHECK(msg->findPointer("reply", (void**)&reply));
404
405            size_t inbandTracks = 0;
406            if (mSource != NULL) {
407                inbandTracks = mSource->getTrackCount();
408            }
409
410            size_t ccTracks = 0;
411            if (mCCDecoder != NULL) {
412                ccTracks = mCCDecoder->getTrackCount();
413            }
414
415            // total track count
416            reply->writeInt32(inbandTracks + ccTracks);
417
418            // write inband tracks
419            for (size_t i = 0; i < inbandTracks; ++i) {
420                writeTrackInfo(reply, mSource->getTrackInfo(i));
421            }
422
423            // write CC track
424            for (size_t i = 0; i < ccTracks; ++i) {
425                writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
426            }
427
428            sp<AMessage> response = new AMessage;
429            response->postReply(replyID);
430            break;
431        }
432
433        case kWhatGetSelectedTrack:
434        {
435            status_t err = INVALID_OPERATION;
436            if (mSource != NULL) {
437                err = OK;
438
439                int32_t type32;
440                CHECK(msg->findInt32("type", (int32_t*)&type32));
441                media_track_type type = (media_track_type)type32;
442                ssize_t selectedTrack = mSource->getSelectedTrack(type);
443
444                Parcel* reply;
445                CHECK(msg->findPointer("reply", (void**)&reply));
446                reply->writeInt32(selectedTrack);
447            }
448
449            sp<AMessage> response = new AMessage;
450            response->setInt32("err", err);
451
452            uint32_t replyID;
453            CHECK(msg->senderAwaitsResponse(&replyID));
454            response->postReply(replyID);
455            break;
456        }
457
458        case kWhatSelectTrack:
459        {
460            uint32_t replyID;
461            CHECK(msg->senderAwaitsResponse(&replyID));
462
463            size_t trackIndex;
464            int32_t select;
465            CHECK(msg->findSize("trackIndex", &trackIndex));
466            CHECK(msg->findInt32("select", &select));
467
468            status_t err = INVALID_OPERATION;
469
470            size_t inbandTracks = 0;
471            if (mSource != NULL) {
472                inbandTracks = mSource->getTrackCount();
473            }
474            size_t ccTracks = 0;
475            if (mCCDecoder != NULL) {
476                ccTracks = mCCDecoder->getTrackCount();
477            }
478
479            if (trackIndex < inbandTracks) {
480                err = mSource->selectTrack(trackIndex, select);
481
482                if (!select && err == OK) {
483                    int32_t type;
484                    sp<AMessage> info = mSource->getTrackInfo(trackIndex);
485                    if (info != NULL
486                            && info->findInt32("type", &type)
487                            && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
488                        ++mTimedTextGeneration;
489                    }
490                }
491            } else {
492                trackIndex -= inbandTracks;
493
494                if (trackIndex < ccTracks) {
495                    err = mCCDecoder->selectTrack(trackIndex, select);
496                }
497            }
498
499            sp<AMessage> response = new AMessage;
500            response->setInt32("err", err);
501
502            response->postReply(replyID);
503            break;
504        }
505
506        case kWhatPollDuration:
507        {
508            int32_t generation;
509            CHECK(msg->findInt32("generation", &generation));
510
511            if (generation != mPollDurationGeneration) {
512                // stale
513                break;
514            }
515
516            int64_t durationUs;
517            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
518                sp<NuPlayerDriver> driver = mDriver.promote();
519                if (driver != NULL) {
520                    driver->notifyDuration(durationUs);
521                }
522            }
523
524            msg->post(1000000ll);  // poll again in a second.
525            break;
526        }
527
528        case kWhatSetVideoNativeWindow:
529        {
530            ALOGV("kWhatSetVideoNativeWindow");
531
532            mDeferredActions.push_back(
533                    new ShutdownDecoderAction(
534                        false /* audio */, true /* video */));
535
536            sp<RefBase> obj;
537            CHECK(msg->findObject("native-window", &obj));
538
539            mDeferredActions.push_back(
540                    new SetSurfaceAction(
541                        static_cast<NativeWindowWrapper *>(obj.get())));
542
543            if (obj != NULL) {
544                if (mStarted && mVideoDecoder != NULL) {
545                    // Issue a seek to refresh the video screen only if started otherwise
546                    // the extractor may not yet be started and will assert.
547                    // If the video decoder is not set (perhaps audio only in this case)
548                    // do not perform a seek as it is not needed.
549                    mDeferredActions.push_back(new SeekAction(mCurrentPositionUs));
550                }
551
552                // If there is a new surface texture, instantiate decoders
553                // again if possible.
554                mDeferredActions.push_back(
555                        new SimpleAction(&NuPlayer::performScanSources));
556            }
557
558            processDeferredActions();
559            break;
560        }
561
562        case kWhatSetAudioSink:
563        {
564            ALOGV("kWhatSetAudioSink");
565
566            sp<RefBase> obj;
567            CHECK(msg->findObject("sink", &obj));
568
569            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
570            break;
571        }
572
573        case kWhatStart:
574        {
575            ALOGV("kWhatStart");
576
577            mVideoIsAVC = false;
578            mOffloadAudio = false;
579            mAudioEOS = false;
580            mVideoEOS = false;
581            mSkipRenderingAudioUntilMediaTimeUs = -1;
582            mSkipRenderingVideoUntilMediaTimeUs = -1;
583            mVideoLateByUs = 0;
584            mNumFramesTotal = 0;
585            mNumFramesDropped = 0;
586            mStarted = true;
587
588            /* instantiate decoders now for secure playback */
589            if (mSourceFlags & Source::FLAG_SECURE) {
590                if (mNativeWindow != NULL) {
591                    instantiateDecoder(false, &mVideoDecoder);
592                }
593
594                if (mAudioSink != NULL) {
595                    instantiateDecoder(true, &mAudioDecoder);
596                }
597            }
598
599            mSource->start();
600
601            uint32_t flags = 0;
602
603            if (mSource->isRealTime()) {
604                flags |= Renderer::FLAG_REAL_TIME;
605            }
606
607            sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
608            audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
609            if (mAudioSink != NULL) {
610                streamType = mAudioSink->getAudioStreamType();
611            }
612
613            sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
614
615            mOffloadAudio =
616                canOffloadStream(audioMeta, (videoFormat != NULL),
617                                 true /* is_streaming */, streamType);
618            if (mOffloadAudio) {
619                flags |= Renderer::FLAG_OFFLOAD_AUDIO;
620            }
621
622            mRenderer = new Renderer(
623                    mAudioSink,
624                    new AMessage(kWhatRendererNotify, id()),
625                    flags);
626
627            mRendererLooper = new ALooper;
628            mRendererLooper->setName("NuPlayerRenderer");
629            mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
630            mRendererLooper->registerHandler(mRenderer);
631
632            postScanSources();
633            break;
634        }
635
636        case kWhatScanSources:
637        {
638            int32_t generation;
639            CHECK(msg->findInt32("generation", &generation));
640            if (generation != mScanSourcesGeneration) {
641                // Drop obsolete msg.
642                break;
643            }
644
645            mScanSourcesPending = false;
646
647            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
648                 mAudioDecoder != NULL, mVideoDecoder != NULL);
649
650            bool mHadAnySourcesBefore =
651                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
652
653            // initialize video before audio because successful initialization of
654            // video may change deep buffer mode of audio.
655            if (mNativeWindow != NULL) {
656                instantiateDecoder(false, &mVideoDecoder);
657            }
658
659            if (mAudioSink != NULL) {
660                if (mOffloadAudio) {
661                    // open audio sink early under offload mode.
662                    sp<AMessage> format = mSource->getFormat(true /*audio*/);
663                    openAudioSink(format, true /*offloadOnly*/);
664                }
665                instantiateDecoder(true, &mAudioDecoder);
666            }
667
668            if (!mHadAnySourcesBefore
669                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
670                // This is the first time we've found anything playable.
671
672                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
673                    schedulePollDuration();
674                }
675            }
676
677            status_t err;
678            if ((err = mSource->feedMoreTSData()) != OK) {
679                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
680                    // We're not currently decoding anything (no audio or
681                    // video tracks found) and we just ran out of input data.
682
683                    if (err == ERROR_END_OF_STREAM) {
684                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
685                    } else {
686                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
687                    }
688                }
689                break;
690            }
691
692            if ((mAudioDecoder == NULL && mAudioSink != NULL)
693                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
694                msg->post(100000ll);
695                mScanSourcesPending = true;
696            }
697            break;
698        }
699
700        case kWhatVideoNotify:
701        case kWhatAudioNotify:
702        {
703            bool audio = msg->what() == kWhatAudioNotify;
704
705            int32_t currentDecoderGeneration =
706                (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
707            int32_t requesterGeneration = currentDecoderGeneration - 1;
708            CHECK(msg->findInt32("generation", &requesterGeneration));
709
710            if (requesterGeneration != currentDecoderGeneration) {
711                ALOGV("got message from old %s decoder, generation(%d:%d)",
712                        audio ? "audio" : "video", requesterGeneration,
713                        currentDecoderGeneration);
714                sp<AMessage> reply;
715                if (!(msg->findMessage("reply", &reply))) {
716                    return;
717                }
718
719                reply->setInt32("err", INFO_DISCONTINUITY);
720                reply->post();
721                return;
722            }
723
724            int32_t what;
725            CHECK(msg->findInt32("what", &what));
726
727            if (what == Decoder::kWhatFillThisBuffer) {
728                status_t err = feedDecoderInputData(
729                        audio, msg);
730
731                if (err == -EWOULDBLOCK) {
732                    if (mSource->feedMoreTSData() == OK) {
733                        msg->post(10000ll);
734                    }
735                }
736            } else if (what == Decoder::kWhatEOS) {
737                int32_t err;
738                CHECK(msg->findInt32("err", &err));
739
740                if (err == ERROR_END_OF_STREAM) {
741                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
742                } else {
743                    ALOGV("got %s decoder EOS w/ error %d",
744                         audio ? "audio" : "video",
745                         err);
746                }
747
748                mRenderer->queueEOS(audio, err);
749            } else if (what == Decoder::kWhatFlushCompleted) {
750                bool needShutdown;
751
752                if (audio) {
753                    CHECK(IsFlushingState(mFlushingAudio, &needShutdown));
754                    mFlushingAudio = FLUSHED;
755                } else {
756                    CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
757                    mFlushingVideo = FLUSHED;
758
759                    mVideoLateByUs = 0;
760                }
761
762                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
763
764                if (needShutdown) {
765                    ALOGV("initiating %s decoder shutdown",
766                         audio ? "audio" : "video");
767
768                    getDecoder(audio)->initiateShutdown();
769
770                    if (audio) {
771                        mFlushingAudio = SHUTTING_DOWN_DECODER;
772                    } else {
773                        mFlushingVideo = SHUTTING_DOWN_DECODER;
774                    }
775                }
776
777                finishFlushIfPossible();
778            } else if (what == Decoder::kWhatOutputFormatChanged) {
779                sp<AMessage> format;
780                CHECK(msg->findMessage("format", &format));
781
782                if (audio) {
783                    openAudioSink(format, false /*offloadOnly*/);
784                } else {
785                    // video
786                    sp<AMessage> inputFormat =
787                            mSource->getFormat(false /* audio */);
788
789                    updateVideoSize(inputFormat, format);
790                }
791            } else if (what == Decoder::kWhatShutdownCompleted) {
792                ALOGV("%s shutdown completed", audio ? "audio" : "video");
793                if (audio) {
794                    mAudioDecoder.clear();
795
796                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
797                    mFlushingAudio = SHUT_DOWN;
798                } else {
799                    mVideoDecoder.clear();
800
801                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
802                    mFlushingVideo = SHUT_DOWN;
803                }
804
805                finishFlushIfPossible();
806            } else if (what == Decoder::kWhatError) {
807                ALOGE("Received error from %s decoder, aborting playback.",
808                     audio ? "audio" : "video");
809
810                status_t err;
811                if (!msg->findInt32("err", &err)) {
812                    err = UNKNOWN_ERROR;
813                }
814                mRenderer->queueEOS(audio, err);
815                if (audio && mFlushingAudio != NONE) {
816                    mAudioDecoder.clear();
817                    mFlushingAudio = SHUT_DOWN;
818                } else if (!audio && mFlushingVideo != NONE){
819                    mVideoDecoder.clear();
820                    mFlushingVideo = SHUT_DOWN;
821                }
822                finishFlushIfPossible();
823            } else if (what == Decoder::kWhatDrainThisBuffer) {
824                renderBuffer(audio, msg);
825            } else {
826                ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
827                      what,
828                      what >> 24,
829                      (what >> 16) & 0xff,
830                      (what >> 8) & 0xff,
831                      what & 0xff);
832            }
833
834            break;
835        }
836
837        case kWhatRendererNotify:
838        {
839            int32_t what;
840            CHECK(msg->findInt32("what", &what));
841
842            if (what == Renderer::kWhatEOS) {
843                int32_t audio;
844                CHECK(msg->findInt32("audio", &audio));
845
846                int32_t finalResult;
847                CHECK(msg->findInt32("finalResult", &finalResult));
848
849                if (audio) {
850                    mAudioEOS = true;
851                } else {
852                    mVideoEOS = true;
853                }
854
855                if (finalResult == ERROR_END_OF_STREAM) {
856                    ALOGV("reached %s EOS", audio ? "audio" : "video");
857                } else {
858                    ALOGE("%s track encountered an error (%d)",
859                         audio ? "audio" : "video", finalResult);
860
861                    notifyListener(
862                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
863                }
864
865                if ((mAudioEOS || mAudioDecoder == NULL)
866                        && (mVideoEOS || mVideoDecoder == NULL)) {
867                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
868                }
869            } else if (what == Renderer::kWhatPosition) {
870                int64_t positionUs;
871                CHECK(msg->findInt64("positionUs", &positionUs));
872                mCurrentPositionUs = positionUs;
873
874                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
875
876                if (mDriver != NULL) {
877                    sp<NuPlayerDriver> driver = mDriver.promote();
878                    if (driver != NULL) {
879                        driver->notifyPosition(positionUs);
880
881                        driver->notifyFrameStats(
882                                mNumFramesTotal, mNumFramesDropped);
883                    }
884                }
885            } else if (what == Renderer::kWhatFlushComplete) {
886                int32_t audio;
887                CHECK(msg->findInt32("audio", &audio));
888
889                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
890            } else if (what == Renderer::kWhatVideoRenderingStart) {
891                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
892            } else if (what == Renderer::kWhatMediaRenderingStart) {
893                ALOGV("media rendering started");
894                notifyListener(MEDIA_STARTED, 0, 0);
895            } else if (what == Renderer::kWhatAudioOffloadTearDown) {
896                ALOGV("Tear down audio offload, fall back to s/w path");
897                int64_t positionUs;
898                CHECK(msg->findInt64("positionUs", &positionUs));
899                closeAudioSink();
900                mAudioDecoder.clear();
901                mRenderer->flush(true /* audio */);
902                if (mVideoDecoder != NULL) {
903                    mRenderer->flush(false /* audio */);
904                }
905                mRenderer->signalDisableOffloadAudio();
906                mOffloadAudio = false;
907
908                performSeek(positionUs);
909                instantiateDecoder(true /* audio */, &mAudioDecoder);
910            }
911            break;
912        }
913
914        case kWhatMoreDataQueued:
915        {
916            break;
917        }
918
919        case kWhatReset:
920        {
921            ALOGV("kWhatReset");
922
923            mDeferredActions.push_back(
924                    new ShutdownDecoderAction(
925                        true /* audio */, true /* video */));
926
927            mDeferredActions.push_back(
928                    new SimpleAction(&NuPlayer::performReset));
929
930            processDeferredActions();
931            break;
932        }
933
934        case kWhatSeek:
935        {
936            int64_t seekTimeUs;
937            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
938
939            ALOGV("kWhatSeek seekTimeUs=%lld us", seekTimeUs);
940
941            mDeferredActions.push_back(
942                    new SimpleAction(&NuPlayer::performDecoderFlush));
943
944            mDeferredActions.push_back(new SeekAction(seekTimeUs));
945
946            processDeferredActions();
947            break;
948        }
949
950        case kWhatPause:
951        {
952            CHECK(mRenderer != NULL);
953            mSource->pause();
954            mRenderer->pause();
955            break;
956        }
957
958        case kWhatResume:
959        {
960            CHECK(mRenderer != NULL);
961            mSource->resume();
962            mRenderer->resume();
963            break;
964        }
965
966        case kWhatSourceNotify:
967        {
968            onSourceNotify(msg);
969            break;
970        }
971
972        case kWhatClosedCaptionNotify:
973        {
974            onClosedCaptionNotify(msg);
975            break;
976        }
977
978        default:
979            TRESPASS();
980            break;
981    }
982}
983
984void NuPlayer::finishFlushIfPossible() {
985    if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
986            && mFlushingAudio != SHUT_DOWN) {
987        return;
988    }
989
990    if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
991            && mFlushingVideo != SHUT_DOWN) {
992        return;
993    }
994
995    ALOGV("both audio and video are flushed now.");
996
997    mPendingAudioAccessUnit.clear();
998
999    if (mTimeDiscontinuityPending) {
1000        mRenderer->signalTimeDiscontinuity();
1001        mTimeDiscontinuityPending = false;
1002    }
1003
1004    if (mAudioDecoder != NULL && mFlushingAudio == FLUSHED) {
1005        mAudioDecoder->signalResume();
1006    }
1007
1008    if (mVideoDecoder != NULL && mFlushingVideo == FLUSHED) {
1009        mVideoDecoder->signalResume();
1010    }
1011
1012    mFlushingAudio = NONE;
1013    mFlushingVideo = NONE;
1014
1015    processDeferredActions();
1016}
1017
1018void NuPlayer::postScanSources() {
1019    if (mScanSourcesPending) {
1020        return;
1021    }
1022
1023    sp<AMessage> msg = new AMessage(kWhatScanSources, id());
1024    msg->setInt32("generation", mScanSourcesGeneration);
1025    msg->post();
1026
1027    mScanSourcesPending = true;
1028}
1029
1030void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
1031    ALOGV("openAudioSink: offloadOnly(%d) mOffloadAudio(%d)",
1032            offloadOnly, mOffloadAudio);
1033    bool audioSinkChanged = false;
1034
1035    int32_t numChannels;
1036    CHECK(format->findInt32("channel-count", &numChannels));
1037
1038    int32_t channelMask;
1039    if (!format->findInt32("channel-mask", &channelMask)) {
1040        // signal to the AudioSink to derive the mask from count.
1041        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
1042    }
1043
1044    int32_t sampleRate;
1045    CHECK(format->findInt32("sample-rate", &sampleRate));
1046
1047    uint32_t flags;
1048    int64_t durationUs;
1049    // FIXME: we should handle the case where the video decoder
1050    // is created after we receive the format change indication.
1051    // Current code will just make that we select deep buffer
1052    // with video which should not be a problem as it should
1053    // not prevent from keeping A/V sync.
1054    if (mVideoDecoder == NULL &&
1055            mSource->getDuration(&durationUs) == OK &&
1056            durationUs
1057                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
1058        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1059    } else {
1060        flags = AUDIO_OUTPUT_FLAG_NONE;
1061    }
1062
1063    if (mOffloadAudio) {
1064        audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
1065        AString mime;
1066        CHECK(format->findString("mime", &mime));
1067        status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
1068
1069        if (err != OK) {
1070            ALOGE("Couldn't map mime \"%s\" to a valid "
1071                    "audio_format", mime.c_str());
1072            mOffloadAudio = false;
1073        } else {
1074            ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
1075                    mime.c_str(), audioFormat);
1076
1077            int avgBitRate = -1;
1078            format->findInt32("bit-rate", &avgBitRate);
1079
1080            int32_t aacProfile = -1;
1081            if (audioFormat == AUDIO_FORMAT_AAC
1082                    && format->findInt32("aac-profile", &aacProfile)) {
1083                // Redefine AAC format as per aac profile
1084                mapAACProfileToAudioFormat(
1085                        audioFormat,
1086                        aacProfile);
1087            }
1088
1089            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
1090            offloadInfo.duration_us = -1;
1091            format->findInt64(
1092                    "durationUs", &offloadInfo.duration_us);
1093            offloadInfo.sample_rate = sampleRate;
1094            offloadInfo.channel_mask = channelMask;
1095            offloadInfo.format = audioFormat;
1096            offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
1097            offloadInfo.bit_rate = avgBitRate;
1098            offloadInfo.has_video = (mVideoDecoder != NULL);
1099            offloadInfo.is_streaming = true;
1100
1101            if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
1102                ALOGV("openAudioSink: no change in offload mode");
1103                return;  // no change from previous configuration, everything ok.
1104            }
1105            ALOGV("openAudioSink: try to open AudioSink in offload mode");
1106            flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
1107            flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1108            audioSinkChanged = true;
1109            mAudioSink->close();
1110            err = mAudioSink->open(
1111                    sampleRate,
1112                    numChannels,
1113                    (audio_channel_mask_t)channelMask,
1114                    audioFormat,
1115                    8 /* bufferCount */,
1116                    &NuPlayer::Renderer::AudioSinkCallback,
1117                    mRenderer.get(),
1118                    (audio_output_flags_t)flags,
1119                    &offloadInfo);
1120
1121            if (err == OK) {
1122                // If the playback is offloaded to h/w, we pass
1123                // the HAL some metadata information.
1124                // We don't want to do this for PCM because it
1125                // will be going through the AudioFlinger mixer
1126                // before reaching the hardware.
1127                sp<MetaData> audioMeta =
1128                        mSource->getFormatMeta(true /* audio */);
1129                sendMetaDataToHal(mAudioSink, audioMeta);
1130                mCurrentOffloadInfo = offloadInfo;
1131                err = mAudioSink->start();
1132                ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
1133            }
1134            if (err != OK) {
1135                // Clean up, fall back to non offload mode.
1136                mAudioSink->close();
1137                mRenderer->signalDisableOffloadAudio();
1138                mOffloadAudio = false;
1139                mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1140                ALOGV("openAudioSink: offload failed");
1141            }
1142        }
1143    }
1144    if (!offloadOnly && !mOffloadAudio) {
1145        flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
1146        ALOGV("openAudioSink: open AudioSink in NON-offload mode");
1147
1148        audioSinkChanged = true;
1149        mAudioSink->close();
1150        mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1151        CHECK_EQ(mAudioSink->open(
1152                    sampleRate,
1153                    numChannels,
1154                    (audio_channel_mask_t)channelMask,
1155                    AUDIO_FORMAT_PCM_16_BIT,
1156                    8 /* bufferCount */,
1157                    NULL,
1158                    NULL,
1159                    (audio_output_flags_t)flags),
1160                 (status_t)OK);
1161        mAudioSink->start();
1162    }
1163    if (audioSinkChanged) {
1164        mRenderer->signalAudioSinkChanged();
1165    }
1166}
1167
1168void NuPlayer::closeAudioSink() {
1169    mAudioSink->close();
1170    mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
1171}
1172
1173status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
1174    if (*decoder != NULL) {
1175        return OK;
1176    }
1177
1178    sp<AMessage> format = mSource->getFormat(audio);
1179
1180    if (format == NULL) {
1181        return -EWOULDBLOCK;
1182    }
1183
1184    if (!audio) {
1185        AString mime;
1186        CHECK(format->findString("mime", &mime));
1187        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
1188
1189        sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, id());
1190        mCCDecoder = new CCDecoder(ccNotify);
1191
1192        if (mSourceFlags & Source::FLAG_SECURE) {
1193            format->setInt32("secure", true);
1194        }
1195    }
1196
1197    if (audio) {
1198        sp<AMessage> notify = new AMessage(kWhatAudioNotify, id());
1199        ++mAudioDecoderGeneration;
1200        notify->setInt32("generation", mAudioDecoderGeneration);
1201
1202        if (mOffloadAudio) {
1203            *decoder = new DecoderPassThrough(notify);
1204        } else {
1205            *decoder = new Decoder(notify);
1206        }
1207    } else {
1208        sp<AMessage> notify = new AMessage(kWhatVideoNotify, id());
1209        ++mVideoDecoderGeneration;
1210        notify->setInt32("generation", mVideoDecoderGeneration);
1211
1212        *decoder = new Decoder(notify, mNativeWindow);
1213    }
1214    (*decoder)->init();
1215    (*decoder)->configure(format);
1216
1217    // allocate buffers to decrypt widevine source buffers
1218    if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1219        Vector<sp<ABuffer> > inputBufs;
1220        CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1221
1222        Vector<MediaBuffer *> mediaBufs;
1223        for (size_t i = 0; i < inputBufs.size(); i++) {
1224            const sp<ABuffer> &buffer = inputBufs[i];
1225            MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1226            mediaBufs.push(mbuf);
1227        }
1228
1229        status_t err = mSource->setBuffers(audio, mediaBufs);
1230        if (err != OK) {
1231            for (size_t i = 0; i < mediaBufs.size(); ++i) {
1232                mediaBufs[i]->release();
1233            }
1234            mediaBufs.clear();
1235            ALOGE("Secure source didn't support secure mediaBufs.");
1236            return err;
1237        }
1238    }
1239    return OK;
1240}
1241
1242status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
1243    sp<AMessage> reply;
1244    CHECK(msg->findMessage("reply", &reply));
1245
1246    if ((audio && mFlushingAudio != NONE)
1247            || (!audio && mFlushingVideo != NONE)
1248            || mSource == NULL) {
1249        reply->setInt32("err", INFO_DISCONTINUITY);
1250        reply->post();
1251        return OK;
1252    }
1253
1254    sp<ABuffer> accessUnit;
1255
1256    // Aggregate smaller buffers into a larger buffer.
1257    // The goal is to reduce power consumption.
1258    // Unfortunately this does not work with the software AAC decoder.
1259    // TODO optimize buffer size for power consumption
1260    // The offload read buffer size is 32 KB but 24 KB uses less power.
1261    const int kAudioBigBufferSizeBytes = 24 * 1024;
1262    bool doBufferAggregation = (audio && mOffloadAudio);
1263    sp<ABuffer> biggerBuffer;
1264    bool needMoreData = false;
1265    int numSmallBuffers = 0;
1266    bool gotTime = false;
1267
1268    bool dropAccessUnit;
1269    do {
1270        status_t err;
1271        // Did we save an accessUnit earlier because of a discontinuity?
1272        if (audio && (mPendingAudioAccessUnit != NULL)) {
1273            accessUnit = mPendingAudioAccessUnit;
1274            mPendingAudioAccessUnit.clear();
1275            err = mPendingAudioErr;
1276            ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit");
1277        } else {
1278            err = mSource->dequeueAccessUnit(audio, &accessUnit);
1279        }
1280
1281        if (err == -EWOULDBLOCK) {
1282            ALOGD("feedDecoderInputData() got EWOULDBLOCK");
1283            if (biggerBuffer == NULL) {
1284                return err;
1285            } else {
1286                break; // Reply with data that we already have.
1287            }
1288        } else if (err != OK) {
1289            if (err == INFO_DISCONTINUITY) {
1290                if (biggerBuffer != NULL) {
1291                    // We already have some data so save this for later.
1292                    mPendingAudioErr = err;
1293                    mPendingAudioAccessUnit = accessUnit;
1294                    accessUnit.clear();
1295                    ALOGD("feedDecoderInputData() save discontinuity for later");
1296                    break;
1297                }
1298                int32_t type;
1299                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
1300
1301                bool formatChange =
1302                    (audio &&
1303                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
1304                    || (!audio &&
1305                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
1306
1307                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
1308
1309                ALOGI("%s discontinuity (formatChange=%d, time=%d)",
1310                     audio ? "audio" : "video", formatChange, timeChange);
1311
1312                if (audio) {
1313                    mSkipRenderingAudioUntilMediaTimeUs = -1;
1314                } else {
1315                    mSkipRenderingVideoUntilMediaTimeUs = -1;
1316                }
1317
1318                if (timeChange) {
1319                    sp<AMessage> extra;
1320                    if (accessUnit->meta()->findMessage("extra", &extra)
1321                            && extra != NULL) {
1322                        int64_t resumeAtMediaTimeUs;
1323                        if (extra->findInt64(
1324                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
1325                            ALOGI("suppressing rendering of %s until %lld us",
1326                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
1327
1328                            if (audio) {
1329                                mSkipRenderingAudioUntilMediaTimeUs =
1330                                    resumeAtMediaTimeUs;
1331                            } else {
1332                                mSkipRenderingVideoUntilMediaTimeUs =
1333                                    resumeAtMediaTimeUs;
1334                            }
1335                        }
1336                    }
1337                }
1338
1339                mTimeDiscontinuityPending =
1340                    mTimeDiscontinuityPending || timeChange;
1341
1342                bool seamlessFormatChange = false;
1343                sp<AMessage> newFormat = mSource->getFormat(audio);
1344                if (formatChange) {
1345                    seamlessFormatChange =
1346                        getDecoder(audio)->supportsSeamlessFormatChange(newFormat);
1347                    // treat seamless format change separately
1348                    formatChange = !seamlessFormatChange;
1349                }
1350                bool shutdownOrFlush = formatChange || timeChange;
1351
1352                // We want to queue up scan-sources only once per discontinuity.
1353                // We control this by doing it only if neither audio nor video are
1354                // flushing or shutting down.  (After handling 1st discontinuity, one
1355                // of the flushing states will not be NONE.)
1356                // No need to scan sources if this discontinuity does not result
1357                // in a flush or shutdown, as the flushing state will stay NONE.
1358                if (mFlushingAudio == NONE && mFlushingVideo == NONE &&
1359                        shutdownOrFlush) {
1360                    // And we'll resume scanning sources once we're done
1361                    // flushing.
1362                    mDeferredActions.push_front(
1363                            new SimpleAction(
1364                                &NuPlayer::performScanSources));
1365                }
1366
1367                if (formatChange /* not seamless */) {
1368                    // must change decoder
1369                    flushDecoder(audio, /* needShutdown = */ true);
1370                } else if (timeChange) {
1371                    // need to flush
1372                    flushDecoder(audio, /* needShutdown = */ false, newFormat);
1373                    err = OK;
1374                } else if (seamlessFormatChange) {
1375                    // reuse existing decoder and don't flush
1376                    updateDecoderFormatWithoutFlush(audio, newFormat);
1377                    err = OK;
1378                } else {
1379                    // This stream is unaffected by the discontinuity
1380                    return -EWOULDBLOCK;
1381                }
1382            }
1383
1384            reply->setInt32("err", err);
1385            reply->post();
1386            return OK;
1387        }
1388
1389        if (!audio) {
1390            ++mNumFramesTotal;
1391        }
1392
1393        dropAccessUnit = false;
1394        if (!audio
1395                && !(mSourceFlags & Source::FLAG_SECURE)
1396                && mVideoLateByUs > 100000ll
1397                && mVideoIsAVC
1398                && !IsAVCReferenceFrame(accessUnit)) {
1399            dropAccessUnit = true;
1400            ++mNumFramesDropped;
1401        }
1402
1403        size_t smallSize = accessUnit->size();
1404        needMoreData = false;
1405        if (doBufferAggregation && (biggerBuffer == NULL)
1406                // Don't bother if only room for a few small buffers.
1407                && (smallSize < (kAudioBigBufferSizeBytes / 3))) {
1408            // Create a larger buffer for combining smaller buffers from the extractor.
1409            biggerBuffer = new ABuffer(kAudioBigBufferSizeBytes);
1410            biggerBuffer->setRange(0, 0); // start empty
1411        }
1412
1413        if (biggerBuffer != NULL) {
1414            int64_t timeUs;
1415            bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs);
1416            // Will the smaller buffer fit?
1417            size_t bigSize = biggerBuffer->size();
1418            size_t roomLeft = biggerBuffer->capacity() - bigSize;
1419            // Should we save this small buffer for the next big buffer?
1420            // If the first small buffer did not have a timestamp then save
1421            // any buffer that does have a timestamp until the next big buffer.
1422            if ((smallSize > roomLeft)
1423                || (!gotTime && (numSmallBuffers > 0) && smallTimestampValid)) {
1424                mPendingAudioErr = err;
1425                mPendingAudioAccessUnit = accessUnit;
1426                accessUnit.clear();
1427            } else {
1428                // Append small buffer to the bigger buffer.
1429                memcpy(biggerBuffer->base() + bigSize, accessUnit->data(), smallSize);
1430                bigSize += smallSize;
1431                biggerBuffer->setRange(0, bigSize);
1432
1433                // Keep looping until we run out of room in the biggerBuffer.
1434                needMoreData = true;
1435
1436                // Grab time from first small buffer if available.
1437                if ((numSmallBuffers == 0) && smallTimestampValid) {
1438                    biggerBuffer->meta()->setInt64("timeUs", timeUs);
1439                    gotTime = true;
1440                }
1441
1442                ALOGV("feedDecoderInputData() #%d, smallSize = %zu, bigSize = %zu, capacity = %zu",
1443                        numSmallBuffers, smallSize, bigSize, biggerBuffer->capacity());
1444                numSmallBuffers++;
1445            }
1446        }
1447    } while (dropAccessUnit || needMoreData);
1448
1449    // ALOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
1450
1451#if 0
1452    int64_t mediaTimeUs;
1453    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
1454    ALOGV("feeding %s input buffer at media time %.2f secs",
1455         audio ? "audio" : "video",
1456         mediaTimeUs / 1E6);
1457#endif
1458
1459    if (!audio) {
1460        mCCDecoder->decode(accessUnit);
1461    }
1462
1463    if (biggerBuffer != NULL) {
1464        ALOGV("feedDecoderInputData() reply with aggregated buffer, %d", numSmallBuffers);
1465        reply->setBuffer("buffer", biggerBuffer);
1466    } else {
1467        reply->setBuffer("buffer", accessUnit);
1468    }
1469
1470    reply->post();
1471
1472    return OK;
1473}
1474
1475void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
1476    // ALOGV("renderBuffer %s", audio ? "audio" : "video");
1477
1478    sp<AMessage> reply;
1479    CHECK(msg->findMessage("reply", &reply));
1480
1481    if ((audio && mFlushingAudio != NONE)
1482            || (!audio && mFlushingVideo != NONE)) {
1483        // We're currently attempting to flush the decoder, in order
1484        // to complete this, the decoder wants all its buffers back,
1485        // so we don't want any output buffers it sent us (from before
1486        // we initiated the flush) to be stuck in the renderer's queue.
1487
1488        ALOGV("we're still flushing the %s decoder, sending its output buffer"
1489             " right back.", audio ? "audio" : "video");
1490
1491        reply->post();
1492        return;
1493    }
1494
1495    sp<ABuffer> buffer;
1496    CHECK(msg->findBuffer("buffer", &buffer));
1497
1498    int64_t mediaTimeUs;
1499    CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
1500
1501    int64_t &skipUntilMediaTimeUs =
1502        audio
1503            ? mSkipRenderingAudioUntilMediaTimeUs
1504            : mSkipRenderingVideoUntilMediaTimeUs;
1505
1506    if (skipUntilMediaTimeUs >= 0) {
1507
1508        if (mediaTimeUs < skipUntilMediaTimeUs) {
1509            ALOGV("dropping %s buffer at time %lld as requested.",
1510                 audio ? "audio" : "video",
1511                 mediaTimeUs);
1512
1513            reply->post();
1514            return;
1515        }
1516
1517        skipUntilMediaTimeUs = -1;
1518    }
1519
1520    if (!audio && mCCDecoder->isSelected()) {
1521        mCCDecoder->display(mediaTimeUs);
1522    }
1523
1524    mRenderer->queueBuffer(audio, buffer, reply);
1525}
1526
1527void NuPlayer::updateVideoSize(
1528        const sp<AMessage> &inputFormat,
1529        const sp<AMessage> &outputFormat) {
1530    if (inputFormat == NULL) {
1531        ALOGW("Unknown video size, reporting 0x0!");
1532        notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1533        return;
1534    }
1535
1536    int32_t displayWidth, displayHeight;
1537    int32_t cropLeft, cropTop, cropRight, cropBottom;
1538
1539    if (outputFormat != NULL) {
1540        int32_t width, height;
1541        CHECK(outputFormat->findInt32("width", &width));
1542        CHECK(outputFormat->findInt32("height", &height));
1543
1544        int32_t cropLeft, cropTop, cropRight, cropBottom;
1545        CHECK(outputFormat->findRect(
1546                    "crop",
1547                    &cropLeft, &cropTop, &cropRight, &cropBottom));
1548
1549        displayWidth = cropRight - cropLeft + 1;
1550        displayHeight = cropBottom - cropTop + 1;
1551
1552        ALOGV("Video output format changed to %d x %d "
1553             "(crop: %d x %d @ (%d, %d))",
1554             width, height,
1555             displayWidth,
1556             displayHeight,
1557             cropLeft, cropTop);
1558    } else {
1559        CHECK(inputFormat->findInt32("width", &displayWidth));
1560        CHECK(inputFormat->findInt32("height", &displayHeight));
1561
1562        ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1563    }
1564
1565    // Take into account sample aspect ratio if necessary:
1566    int32_t sarWidth, sarHeight;
1567    if (inputFormat->findInt32("sar-width", &sarWidth)
1568            && inputFormat->findInt32("sar-height", &sarHeight)) {
1569        ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1570
1571        displayWidth = (displayWidth * sarWidth) / sarHeight;
1572
1573        ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1574    }
1575
1576    int32_t rotationDegrees;
1577    if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1578        rotationDegrees = 0;
1579    }
1580
1581    if (rotationDegrees == 90 || rotationDegrees == 270) {
1582        int32_t tmp = displayWidth;
1583        displayWidth = displayHeight;
1584        displayHeight = tmp;
1585    }
1586
1587    notifyListener(
1588            MEDIA_SET_VIDEO_SIZE,
1589            displayWidth,
1590            displayHeight);
1591}
1592
1593void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
1594    if (mDriver == NULL) {
1595        return;
1596    }
1597
1598    sp<NuPlayerDriver> driver = mDriver.promote();
1599
1600    if (driver == NULL) {
1601        return;
1602    }
1603
1604    driver->notifyListener(msg, ext1, ext2, in);
1605}
1606
1607void NuPlayer::flushDecoder(
1608        bool audio, bool needShutdown, const sp<AMessage> &newFormat) {
1609    ALOGV("[%s] flushDecoder needShutdown=%d",
1610          audio ? "audio" : "video", needShutdown);
1611
1612    const sp<Decoder> &decoder = getDecoder(audio);
1613    if (decoder == NULL) {
1614        ALOGI("flushDecoder %s without decoder present",
1615             audio ? "audio" : "video");
1616        return;
1617    }
1618
1619    // Make sure we don't continue to scan sources until we finish flushing.
1620    ++mScanSourcesGeneration;
1621    mScanSourcesPending = false;
1622
1623    decoder->signalFlush(newFormat);
1624    mRenderer->flush(audio);
1625
1626    FlushStatus newStatus =
1627        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1628
1629    if (audio) {
1630        ALOGE_IF(mFlushingAudio != NONE,
1631                "audio flushDecoder() is called in state %d", mFlushingAudio);
1632        mFlushingAudio = newStatus;
1633    } else {
1634        ALOGE_IF(mFlushingVideo != NONE,
1635                "video flushDecoder() is called in state %d", mFlushingVideo);
1636        mFlushingVideo = newStatus;
1637
1638        if (mCCDecoder != NULL) {
1639            mCCDecoder->flush();
1640        }
1641    }
1642}
1643
1644void NuPlayer::updateDecoderFormatWithoutFlush(
1645        bool audio, const sp<AMessage> &format) {
1646    ALOGV("[%s] updateDecoderFormatWithoutFlush", audio ? "audio" : "video");
1647
1648    const sp<Decoder> &decoder = getDecoder(audio);
1649    if (decoder == NULL) {
1650        ALOGI("updateDecoderFormatWithoutFlush %s without decoder present",
1651             audio ? "audio" : "video");
1652        return;
1653    }
1654
1655    decoder->signalUpdateFormat(format);
1656}
1657
1658void NuPlayer::queueDecoderShutdown(
1659        bool audio, bool video, const sp<AMessage> &reply) {
1660    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1661
1662    mDeferredActions.push_back(
1663            new ShutdownDecoderAction(audio, video));
1664
1665    mDeferredActions.push_back(
1666            new SimpleAction(&NuPlayer::performScanSources));
1667
1668    mDeferredActions.push_back(new PostMessageAction(reply));
1669
1670    processDeferredActions();
1671}
1672
1673status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1674    mVideoScalingMode = mode;
1675    if (mNativeWindow != NULL) {
1676        status_t ret = native_window_set_scaling_mode(
1677                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1678        if (ret != OK) {
1679            ALOGE("Failed to set scaling mode (%d): %s",
1680                -ret, strerror(-ret));
1681            return ret;
1682        }
1683    }
1684    return OK;
1685}
1686
1687status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1688    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, id());
1689    msg->setPointer("reply", reply);
1690
1691    sp<AMessage> response;
1692    status_t err = msg->postAndAwaitResponse(&response);
1693    return err;
1694}
1695
1696status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
1697    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, id());
1698    msg->setPointer("reply", reply);
1699    msg->setInt32("type", type);
1700
1701    sp<AMessage> response;
1702    status_t err = msg->postAndAwaitResponse(&response);
1703    if (err == OK && response != NULL) {
1704        CHECK(response->findInt32("err", &err));
1705    }
1706    return err;
1707}
1708
1709status_t NuPlayer::selectTrack(size_t trackIndex, bool select) {
1710    sp<AMessage> msg = new AMessage(kWhatSelectTrack, id());
1711    msg->setSize("trackIndex", trackIndex);
1712    msg->setInt32("select", select);
1713
1714    sp<AMessage> response;
1715    status_t err = msg->postAndAwaitResponse(&response);
1716
1717    if (err != OK) {
1718        return err;
1719    }
1720
1721    if (!response->findInt32("err", &err)) {
1722        err = OK;
1723    }
1724
1725    return err;
1726}
1727
1728void NuPlayer::schedulePollDuration() {
1729    sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
1730    msg->setInt32("generation", mPollDurationGeneration);
1731    msg->post();
1732}
1733
1734void NuPlayer::cancelPollDuration() {
1735    ++mPollDurationGeneration;
1736}
1737
1738void NuPlayer::processDeferredActions() {
1739    while (!mDeferredActions.empty()) {
1740        // We won't execute any deferred actions until we're no longer in
1741        // an intermediate state, i.e. one more more decoders are currently
1742        // flushing or shutting down.
1743
1744        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1745            // We're currently flushing, postpone the reset until that's
1746            // completed.
1747
1748            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1749                  mFlushingAudio, mFlushingVideo);
1750
1751            break;
1752        }
1753
1754        sp<Action> action = *mDeferredActions.begin();
1755        mDeferredActions.erase(mDeferredActions.begin());
1756
1757        action->execute(this);
1758    }
1759}
1760
1761void NuPlayer::performSeek(int64_t seekTimeUs) {
1762    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
1763          seekTimeUs,
1764          seekTimeUs / 1E6);
1765
1766    if (mSource == NULL) {
1767        // This happens when reset occurs right before the loop mode
1768        // asynchronously seeks to the start of the stream.
1769        LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
1770                "mSource is NULL and decoders not NULL audio(%p) video(%p)",
1771                mAudioDecoder.get(), mVideoDecoder.get());
1772        return;
1773    }
1774    mSource->seekTo(seekTimeUs);
1775    ++mTimedTextGeneration;
1776
1777    if (mDriver != NULL) {
1778        sp<NuPlayerDriver> driver = mDriver.promote();
1779        if (driver != NULL) {
1780            driver->notifyPosition(seekTimeUs);
1781            driver->notifySeekComplete();
1782        }
1783    }
1784
1785    // everything's flushed, continue playback.
1786}
1787
1788void NuPlayer::performDecoderFlush() {
1789    ALOGV("performDecoderFlush");
1790
1791    if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
1792        return;
1793    }
1794
1795    mTimeDiscontinuityPending = true;
1796
1797    if (mAudioDecoder != NULL) {
1798        flushDecoder(true /* audio */, false /* needShutdown */);
1799    }
1800
1801    if (mVideoDecoder != NULL) {
1802        flushDecoder(false /* audio */, false /* needShutdown */);
1803    }
1804}
1805
1806void NuPlayer::performDecoderShutdown(bool audio, bool video) {
1807    ALOGV("performDecoderShutdown audio=%d, video=%d", audio, video);
1808
1809    if ((!audio || mAudioDecoder == NULL)
1810            && (!video || mVideoDecoder == NULL)) {
1811        return;
1812    }
1813
1814    mTimeDiscontinuityPending = true;
1815
1816    if (audio && mAudioDecoder != NULL) {
1817        flushDecoder(true /* audio */, true /* needShutdown */);
1818    }
1819
1820    if (video && mVideoDecoder != NULL) {
1821        flushDecoder(false /* audio */, true /* needShutdown */);
1822    }
1823}
1824
1825void NuPlayer::performReset() {
1826    ALOGV("performReset");
1827
1828    CHECK(mAudioDecoder == NULL);
1829    CHECK(mVideoDecoder == NULL);
1830
1831    cancelPollDuration();
1832
1833    ++mScanSourcesGeneration;
1834    mScanSourcesPending = false;
1835
1836    ++mAudioDecoderGeneration;
1837    ++mVideoDecoderGeneration;
1838
1839    if (mRendererLooper != NULL) {
1840        if (mRenderer != NULL) {
1841            mRendererLooper->unregisterHandler(mRenderer->id());
1842        }
1843        mRendererLooper->stop();
1844        mRendererLooper.clear();
1845    }
1846    mRenderer.clear();
1847
1848    if (mSource != NULL) {
1849        mSource->stop();
1850
1851        mSource.clear();
1852    }
1853
1854    if (mDriver != NULL) {
1855        sp<NuPlayerDriver> driver = mDriver.promote();
1856        if (driver != NULL) {
1857            driver->notifyResetComplete();
1858        }
1859    }
1860
1861    mStarted = false;
1862}
1863
1864void NuPlayer::performScanSources() {
1865    ALOGV("performScanSources");
1866
1867    if (!mStarted) {
1868        return;
1869    }
1870
1871    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1872        postScanSources();
1873    }
1874}
1875
1876void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1877    ALOGV("performSetSurface");
1878
1879    mNativeWindow = wrapper;
1880
1881    // XXX - ignore error from setVideoScalingMode for now
1882    setVideoScalingMode(mVideoScalingMode);
1883
1884    if (mDriver != NULL) {
1885        sp<NuPlayerDriver> driver = mDriver.promote();
1886        if (driver != NULL) {
1887            driver->notifySetSurfaceComplete();
1888        }
1889    }
1890}
1891
1892void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1893    int32_t what;
1894    CHECK(msg->findInt32("what", &what));
1895
1896    switch (what) {
1897        case Source::kWhatPrepared:
1898        {
1899            if (mSource == NULL) {
1900                // This is a stale notification from a source that was
1901                // asynchronously preparing when the client called reset().
1902                // We handled the reset, the source is gone.
1903                break;
1904            }
1905
1906            int32_t err;
1907            CHECK(msg->findInt32("err", &err));
1908
1909            sp<NuPlayerDriver> driver = mDriver.promote();
1910            if (driver != NULL) {
1911                // notify duration first, so that it's definitely set when
1912                // the app received the "prepare complete" callback.
1913                int64_t durationUs;
1914                if (mSource->getDuration(&durationUs) == OK) {
1915                    driver->notifyDuration(durationUs);
1916                }
1917                driver->notifyPrepareCompleted(err);
1918            }
1919
1920            break;
1921        }
1922
1923        case Source::kWhatFlagsChanged:
1924        {
1925            uint32_t flags;
1926            CHECK(msg->findInt32("flags", (int32_t *)&flags));
1927
1928            sp<NuPlayerDriver> driver = mDriver.promote();
1929            if (driver != NULL) {
1930                driver->notifyFlagsChanged(flags);
1931            }
1932
1933            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1934                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1935                cancelPollDuration();
1936            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1937                    && (flags & Source::FLAG_DYNAMIC_DURATION)
1938                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1939                schedulePollDuration();
1940            }
1941
1942            mSourceFlags = flags;
1943            break;
1944        }
1945
1946        case Source::kWhatVideoSizeChanged:
1947        {
1948            sp<AMessage> format;
1949            CHECK(msg->findMessage("format", &format));
1950
1951            updateVideoSize(format);
1952            break;
1953        }
1954
1955        case Source::kWhatBufferingUpdate:
1956        {
1957            int32_t percentage;
1958            CHECK(msg->findInt32("percentage", &percentage));
1959
1960            notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
1961            break;
1962        }
1963
1964        case Source::kWhatBufferingStart:
1965        {
1966            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1967            break;
1968        }
1969
1970        case Source::kWhatBufferingEnd:
1971        {
1972            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1973            break;
1974        }
1975
1976        case Source::kWhatSubtitleData:
1977        {
1978            sp<ABuffer> buffer;
1979            CHECK(msg->findBuffer("buffer", &buffer));
1980
1981            sendSubtitleData(buffer, 0 /* baseIndex */);
1982            break;
1983        }
1984
1985        case Source::kWhatTimedTextData:
1986        {
1987            int32_t generation;
1988            if (msg->findInt32("generation", &generation)
1989                    && generation != mTimedTextGeneration) {
1990                break;
1991            }
1992
1993            sp<ABuffer> buffer;
1994            CHECK(msg->findBuffer("buffer", &buffer));
1995
1996            sp<NuPlayerDriver> driver = mDriver.promote();
1997            if (driver == NULL) {
1998                break;
1999            }
2000
2001            int posMs;
2002            int64_t timeUs, posUs;
2003            driver->getCurrentPosition(&posMs);
2004            posUs = posMs * 1000;
2005            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2006
2007            if (posUs < timeUs) {
2008                if (!msg->findInt32("generation", &generation)) {
2009                    msg->setInt32("generation", mTimedTextGeneration);
2010                }
2011                msg->post(timeUs - posUs);
2012            } else {
2013                sendTimedTextData(buffer);
2014            }
2015            break;
2016        }
2017
2018        case Source::kWhatQueueDecoderShutdown:
2019        {
2020            int32_t audio, video;
2021            CHECK(msg->findInt32("audio", &audio));
2022            CHECK(msg->findInt32("video", &video));
2023
2024            sp<AMessage> reply;
2025            CHECK(msg->findMessage("reply", &reply));
2026
2027            queueDecoderShutdown(audio, video, reply);
2028            break;
2029        }
2030
2031        case Source::kWhatDrmNoLicense:
2032        {
2033            notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
2034            break;
2035        }
2036
2037        default:
2038            TRESPASS();
2039    }
2040}
2041
2042void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
2043    int32_t what;
2044    CHECK(msg->findInt32("what", &what));
2045
2046    switch (what) {
2047        case NuPlayer::CCDecoder::kWhatClosedCaptionData:
2048        {
2049            sp<ABuffer> buffer;
2050            CHECK(msg->findBuffer("buffer", &buffer));
2051
2052            size_t inbandTracks = 0;
2053            if (mSource != NULL) {
2054                inbandTracks = mSource->getTrackCount();
2055            }
2056
2057            sendSubtitleData(buffer, inbandTracks);
2058            break;
2059        }
2060
2061        case NuPlayer::CCDecoder::kWhatTrackAdded:
2062        {
2063            notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
2064
2065            break;
2066        }
2067
2068        default:
2069            TRESPASS();
2070    }
2071
2072
2073}
2074
2075void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
2076    int32_t trackIndex;
2077    int64_t timeUs, durationUs;
2078    CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
2079    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2080    CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
2081
2082    Parcel in;
2083    in.writeInt32(trackIndex + baseIndex);
2084    in.writeInt64(timeUs);
2085    in.writeInt64(durationUs);
2086    in.writeInt32(buffer->size());
2087    in.writeInt32(buffer->size());
2088    in.write(buffer->data(), buffer->size());
2089
2090    notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
2091}
2092
2093void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
2094    const void *data;
2095    size_t size = 0;
2096    int64_t timeUs;
2097    int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
2098
2099    AString mime;
2100    CHECK(buffer->meta()->findString("mime", &mime));
2101    CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2102
2103    data = buffer->data();
2104    size = buffer->size();
2105
2106    Parcel parcel;
2107    if (size > 0) {
2108        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2109        flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
2110        TextDescriptions::getParcelOfDescriptions(
2111                (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2112    }
2113
2114    if ((parcel.dataSize() > 0)) {
2115        notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2116    } else {  // send an empty timed text
2117        notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2118    }
2119}
2120////////////////////////////////////////////////////////////////////////////////
2121
2122sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
2123    sp<MetaData> meta = getFormatMeta(audio);
2124
2125    if (meta == NULL) {
2126        return NULL;
2127    }
2128
2129    sp<AMessage> msg = new AMessage;
2130
2131    if(convertMetaDataToMessage(meta, &msg) == OK) {
2132        return msg;
2133    }
2134    return NULL;
2135}
2136
2137void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
2138    sp<AMessage> notify = dupNotify();
2139    notify->setInt32("what", kWhatFlagsChanged);
2140    notify->setInt32("flags", flags);
2141    notify->post();
2142}
2143
2144void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
2145    sp<AMessage> notify = dupNotify();
2146    notify->setInt32("what", kWhatVideoSizeChanged);
2147    notify->setMessage("format", format);
2148    notify->post();
2149}
2150
2151void NuPlayer::Source::notifyPrepared(status_t err) {
2152    sp<AMessage> notify = dupNotify();
2153    notify->setInt32("what", kWhatPrepared);
2154    notify->setInt32("err", err);
2155    notify->post();
2156}
2157
2158void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
2159    TRESPASS();
2160}
2161
2162}  // namespace android
2163