NuPlayer.cpp revision 3b032b3865fd93173aadca0591eeea32853206f9
188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey/*
288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * Copyright (C) 2010 The Android Open Source Project
388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey *
488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * you may not use this file except in compliance with the License.
688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * You may obtain a copy of the License at
788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey *
888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey *
1088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * Unless required by applicable law or agreed to in writing, software
1188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * See the License for the specific language governing permissions and
1488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey * limitations under the License.
1588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey */
1688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
1788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey//#define LOG_NDEBUG 0
1888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#define LOG_TAG "NuPlayer"
1988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <utils/Log.h>
2088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
2188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayer.h"
2288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
23871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include "HTTPLiveSource.h"
2488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerCCDecoder.h"
2588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerDecoder.h"
2688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerDecoderBase.h"
2788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerDecoderPassThrough.h"
2888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerDriver.h"
2988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerRenderer.h"
3088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "NuPlayerSource.h"
3188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "RTSPSource.h"
3288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "StreamingSource.h"
3388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "GenericSource.h"
3488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "TextDescriptions.h"
3588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
3688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "ATSParser.h"
3788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
3888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <cutils/properties.h>
3988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
4088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/foundation/hexdump.h>
4188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/foundation/ABuffer.h>
4288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/foundation/ADebug.h>
4388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/foundation/AMessage.h>
4488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/MediaBuffer.h>
4588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/MediaDefs.h>
4688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/MediaErrors.h>
4788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/MetaData.h>
4888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <gui/IGraphicBufferProducer.h>
4988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
5088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "avc_utils.h"
5188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
5288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include "ESDS.h"
5388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey#include <media/stagefright/Utils.h>
54d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
55d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkeynamespace android {
56d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
57d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkeystruct NuPlayer::Action : public RefBase {
5888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    Action() {}
59d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
6088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    virtual void execute(NuPlayer *player) = 0;
6188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
6288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeyprivate:
6388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(Action);
6488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey};
6588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
6688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeystruct NuPlayer::SeekAction : public Action {
6788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    SeekAction(int64_t seekTimeUs, bool needNotify)
6888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey        : mSeekTimeUs(seekTimeUs),
6988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey          mNeedNotify(needNotify) {
7088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    }
7188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
72d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    virtual void execute(NuPlayer *player) {
73d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey        player->performSeek(mSeekTimeUs, mNeedNotify);
74d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    }
75d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
76d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkeyprivate:
77d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    int64_t mSeekTimeUs;
78d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    bool mNeedNotify;
79d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
80d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
81d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey};
82d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
83d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkeystruct NuPlayer::ResumeDecoderAction : public Action {
84d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    ResumeDecoderAction(bool needNotify)
85d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey        : mNeedNotify(needNotify) {
86d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    }
87d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
88d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    virtual void execute(NuPlayer *player) {
89d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey        player->performResumeDecoders(mNeedNotify);
90d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    }
91d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
92d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkeyprivate:
93d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    bool mNeedNotify;
94d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
95d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
96d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey};
97d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey
98d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkeystruct NuPlayer::SetSurfaceAction : public Action {
99d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
100d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey        : mWrapper(wrapper) {
101d712f0ccc120357e1267a04ac6de9dd732b27e76Jeff Sharkey    }
10288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
10388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    virtual void execute(NuPlayer *player) {
10488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey        player->performSetSurface(mWrapper);
10588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    }
106b26786d647b624498c11405075e5223d1853f30aJeff Sharkey
10788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeyprivate:
10888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    sp<NativeWindowWrapper> mWrapper;
10988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
110871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
111871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey};
112871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
113871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystruct NuPlayer::FlushDecoderAction : public Action {
11488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    FlushDecoderAction(FlushCommand audio, FlushCommand video)
11588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey        : mAudio(audio),
116871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey          mVideo(video) {
117871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
118871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
119871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    virtual void execute(NuPlayer *player) {
120871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        player->performDecoderFlush(mAudio, mVideo);
121871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
122871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
123871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyprivate:
124871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    FlushCommand mAudio;
125871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    FlushCommand mVideo;
126871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
127871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
128871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey};
129ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey
130871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystruct NuPlayer::PostMessageAction : public Action {
131871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    PostMessageAction(const sp<AMessage> &msg)
132ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey        : mMessage(msg) {
133ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    }
134871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
135871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    virtual void execute(NuPlayer *) {
136871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        mMessage->post();
137871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
138871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
139871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyprivate:
140871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    sp<AMessage> mMessage;
141871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
142871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
143871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey};
144871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
145871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey// Use this if there's no state necessary to save in order to execute
146871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey// the action.
147871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystruct NuPlayer::SimpleAction : public Action {
148871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    typedef void (NuPlayer::*ActionFunc)();
14988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
150871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    SimpleAction(ActionFunc func)
151871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        : mFunc(func) {
152871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
15388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
15488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    virtual void execute(NuPlayer *player) {
15588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey        (player->*mFunc)();
156871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
157871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
158871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyprivate:
159871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    ActionFunc mFunc;
160871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
161871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
162871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey};
16388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
16488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey////////////////////////////////////////////////////////////////////////////////
16588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
16688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff SharkeyNuPlayer::NuPlayer()
16788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    : mUIDValid(false),
16888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mSourceFlags(0),
16988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mOffloadAudio(false),
17088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mAudioDecoderGeneration(0),
17188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mVideoDecoderGeneration(0),
17288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mRendererGeneration(0),
17388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mAudioEOS(false),
17488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mVideoEOS(false),
17588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mScanSourcesPending(false),
17688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mScanSourcesGeneration(0),
17788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mPollDurationGeneration(0),
17888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mTimedTextGeneration(0),
17988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mFlushingAudio(NONE),
18088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mFlushingVideo(NONE),
18188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mResumePending(false),
18288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
18388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mPlaybackRate(1.0),
18488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mStarted(false),
18588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mPaused(false),
18688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey      mPausedByClient(false) {
18788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    clearFlushComplete();
18888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey}
18988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
190871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff SharkeyNuPlayer::~NuPlayer() {
19188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey}
19288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
19388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeyvoid NuPlayer::setUID(uid_t uid) {
19488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    mUIDValid = true;
19588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    mUID = uid;
19688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey}
19788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
19888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeyvoid NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
19988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    mDriver = driver;
20088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey}
20188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
20288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeyvoid NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
20388ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
20488ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
20588ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
20688ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
20788ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    msg->setObject("source", new StreamingSource(notify, source));
20888ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    msg->post();
20988ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey}
21088ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey
21188ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkeystatic bool IsHTTPLiveURL(const char *url) {
21288ddd94834dae9c5862a07a1e4432b171b2f5d9fJeff Sharkey    if (!strncasecmp("http://", url, 7)
213            || !strncasecmp("https://", url, 8)
214            || !strncasecmp("file://", url, 7)) {
215        size_t len = strlen(url);
216        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
217            return true;
218        }
219
220        if (strstr(url,"m3u8")) {
221            return true;
222        }
223    }
224
225    return false;
226}
227
228void NuPlayer::setDataSourceAsync(
229        const sp<IMediaHTTPService> &httpService,
230        const char *url,
231        const KeyedVector<String8, String8> *headers) {
232
233    sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
234    size_t len = strlen(url);
235
236    sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
237
238    sp<Source> source;
239    if (IsHTTPLiveURL(url)) {
240        source = new HTTPLiveSource(notify, httpService, url, headers);
241    } else if (!strncasecmp(url, "rtsp://", 7)) {
242        source = new RTSPSource(
243                notify, httpService, url, headers, mUIDValid, mUID);
244    } else if ((!strncasecmp(url, "http://", 7)
245                || !strncasecmp(url, "https://", 8))
246                    && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
247                    || strstr(url, ".sdp?"))) {
248        source = new RTSPSource(
249                notify, httpService, url, headers, mUIDValid, mUID, true);
250    } else {
251        sp<GenericSource> genericSource =
252                new GenericSource(notify, mUIDValid, mUID);
253        // Don't set FLAG_SECURE on mSourceFlags here for widevine.
254        // The correct flags will be updated in Source::kWhatFlagsChanged
255        // handler when  GenericSource is prepared.
256
257        status_t err = genericSource->setDataSource(httpService, url, headers);
258
259        if (err == OK) {
260            source = genericSource;
261        } else {
262            ALOGE("Failed to set data source!");
263        }
264    }
265    msg->setObject("source", source);
266    msg->post();
267}
268
269void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {
270    sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
271
272    sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
273
274    sp<GenericSource> source =
275            new GenericSource(notify, mUIDValid, mUID);
276
277    status_t err = source->setDataSource(fd, offset, length);
278
279    if (err != OK) {
280        ALOGE("Failed to set data source!");
281        source = NULL;
282    }
283
284    msg->setObject("source", source);
285    msg->post();
286}
287
288void NuPlayer::setDataSourceAsync(const sp<DataSource> &dataSource) {
289    sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
290    sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
291
292    sp<GenericSource> source = new GenericSource(notify, mUIDValid, mUID);
293    status_t err = source->setDataSource(dataSource);
294
295    if (err != OK) {
296        ALOGE("Failed to set data source!");
297        source = NULL;
298    }
299
300    msg->setObject("source", source);
301    msg->post();
302}
303
304void NuPlayer::prepareAsync() {
305    (new AMessage(kWhatPrepare, this))->post();
306}
307
308void NuPlayer::setVideoSurfaceTextureAsync(
309        const sp<IGraphicBufferProducer> &bufferProducer) {
310    sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, this);
311
312    if (bufferProducer == NULL) {
313        msg->setObject("native-window", NULL);
314    } else {
315        msg->setObject(
316                "native-window",
317                new NativeWindowWrapper(
318                    new Surface(bufferProducer, true /* controlledByApp */)));
319    }
320
321    msg->post();
322}
323
324void NuPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
325    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
326    msg->setObject("sink", sink);
327    msg->post();
328}
329
330void NuPlayer::start() {
331    (new AMessage(kWhatStart, this))->post();
332}
333
334void NuPlayer::setPlaybackRate(float rate) {
335    sp<AMessage> msg = new AMessage(kWhatSetRate, this);
336    msg->setFloat("rate", rate);
337    msg->post();
338}
339
340void NuPlayer::pause() {
341    (new AMessage(kWhatPause, this))->post();
342}
343
344void NuPlayer::resetAsync() {
345    if (mSource != NULL) {
346        // During a reset, the data source might be unresponsive already, we need to
347        // disconnect explicitly so that reads exit promptly.
348        // We can't queue the disconnect request to the looper, as it might be
349        // queued behind a stuck read and never gets processed.
350        // Doing a disconnect outside the looper to allows the pending reads to exit
351        // (either successfully or with error).
352        mSource->disconnect();
353    }
354
355    (new AMessage(kWhatReset, this))->post();
356}
357
358void NuPlayer::seekToAsync(int64_t seekTimeUs, bool needNotify) {
359    sp<AMessage> msg = new AMessage(kWhatSeek, this);
360    msg->setInt64("seekTimeUs", seekTimeUs);
361    msg->setInt32("needNotify", needNotify);
362    msg->post();
363}
364
365
366void NuPlayer::writeTrackInfo(
367        Parcel* reply, const sp<AMessage> format) const {
368    int32_t trackType;
369    CHECK(format->findInt32("type", &trackType));
370
371    AString lang;
372    CHECK(format->findString("language", &lang));
373
374    reply->writeInt32(2); // write something non-zero
375    reply->writeInt32(trackType);
376    reply->writeString16(String16(lang.c_str()));
377
378    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
379        AString mime;
380        CHECK(format->findString("mime", &mime));
381
382        int32_t isAuto, isDefault, isForced;
383        CHECK(format->findInt32("auto", &isAuto));
384        CHECK(format->findInt32("default", &isDefault));
385        CHECK(format->findInt32("forced", &isForced));
386
387        reply->writeString16(String16(mime.c_str()));
388        reply->writeInt32(isAuto);
389        reply->writeInt32(isDefault);
390        reply->writeInt32(isForced);
391    }
392}
393
394void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
395    switch (msg->what()) {
396        case kWhatSetDataSource:
397        {
398            ALOGV("kWhatSetDataSource");
399
400            CHECK(mSource == NULL);
401
402            status_t err = OK;
403            sp<RefBase> obj;
404            CHECK(msg->findObject("source", &obj));
405            if (obj != NULL) {
406                mSource = static_cast<Source *>(obj.get());
407            } else {
408                err = UNKNOWN_ERROR;
409            }
410
411            CHECK(mDriver != NULL);
412            sp<NuPlayerDriver> driver = mDriver.promote();
413            if (driver != NULL) {
414                driver->notifySetDataSourceCompleted(err);
415            }
416            break;
417        }
418
419        case kWhatPrepare:
420        {
421            mSource->prepareAsync();
422            break;
423        }
424
425        case kWhatGetTrackInfo:
426        {
427            sp<AReplyToken> replyID;
428            CHECK(msg->senderAwaitsResponse(&replyID));
429
430            Parcel* reply;
431            CHECK(msg->findPointer("reply", (void**)&reply));
432
433            size_t inbandTracks = 0;
434            if (mSource != NULL) {
435                inbandTracks = mSource->getTrackCount();
436            }
437
438            size_t ccTracks = 0;
439            if (mCCDecoder != NULL) {
440                ccTracks = mCCDecoder->getTrackCount();
441            }
442
443            // total track count
444            reply->writeInt32(inbandTracks + ccTracks);
445
446            // write inband tracks
447            for (size_t i = 0; i < inbandTracks; ++i) {
448                writeTrackInfo(reply, mSource->getTrackInfo(i));
449            }
450
451            // write CC track
452            for (size_t i = 0; i < ccTracks; ++i) {
453                writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
454            }
455
456            sp<AMessage> response = new AMessage;
457            response->postReply(replyID);
458            break;
459        }
460
461        case kWhatGetSelectedTrack:
462        {
463            status_t err = INVALID_OPERATION;
464            if (mSource != NULL) {
465                err = OK;
466
467                int32_t type32;
468                CHECK(msg->findInt32("type", (int32_t*)&type32));
469                media_track_type type = (media_track_type)type32;
470                ssize_t selectedTrack = mSource->getSelectedTrack(type);
471
472                Parcel* reply;
473                CHECK(msg->findPointer("reply", (void**)&reply));
474                reply->writeInt32(selectedTrack);
475            }
476
477            sp<AMessage> response = new AMessage;
478            response->setInt32("err", err);
479
480            sp<AReplyToken> replyID;
481            CHECK(msg->senderAwaitsResponse(&replyID));
482            response->postReply(replyID);
483            break;
484        }
485
486        case kWhatSelectTrack:
487        {
488            sp<AReplyToken> replyID;
489            CHECK(msg->senderAwaitsResponse(&replyID));
490
491            size_t trackIndex;
492            int32_t select;
493            int64_t timeUs;
494            CHECK(msg->findSize("trackIndex", &trackIndex));
495            CHECK(msg->findInt32("select", &select));
496            CHECK(msg->findInt64("timeUs", &timeUs));
497
498            status_t err = INVALID_OPERATION;
499
500            size_t inbandTracks = 0;
501            if (mSource != NULL) {
502                inbandTracks = mSource->getTrackCount();
503            }
504            size_t ccTracks = 0;
505            if (mCCDecoder != NULL) {
506                ccTracks = mCCDecoder->getTrackCount();
507            }
508
509            if (trackIndex < inbandTracks) {
510                err = mSource->selectTrack(trackIndex, select, timeUs);
511
512                if (!select && err == OK) {
513                    int32_t type;
514                    sp<AMessage> info = mSource->getTrackInfo(trackIndex);
515                    if (info != NULL
516                            && info->findInt32("type", &type)
517                            && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
518                        ++mTimedTextGeneration;
519                    }
520                }
521            } else {
522                trackIndex -= inbandTracks;
523
524                if (trackIndex < ccTracks) {
525                    err = mCCDecoder->selectTrack(trackIndex, select);
526                }
527            }
528
529            sp<AMessage> response = new AMessage;
530            response->setInt32("err", err);
531
532            response->postReply(replyID);
533            break;
534        }
535
536        case kWhatPollDuration:
537        {
538            int32_t generation;
539            CHECK(msg->findInt32("generation", &generation));
540
541            if (generation != mPollDurationGeneration) {
542                // stale
543                break;
544            }
545
546            int64_t durationUs;
547            if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
548                sp<NuPlayerDriver> driver = mDriver.promote();
549                if (driver != NULL) {
550                    driver->notifyDuration(durationUs);
551                }
552            }
553
554            msg->post(1000000ll);  // poll again in a second.
555            break;
556        }
557
558        case kWhatSetVideoNativeWindow:
559        {
560            ALOGV("kWhatSetVideoNativeWindow");
561
562            sp<RefBase> obj;
563            CHECK(msg->findObject("native-window", &obj));
564
565            if (mSource == NULL || mSource->getFormat(false /* audio */) == NULL) {
566                performSetSurface(static_cast<NativeWindowWrapper *>(obj.get()));
567                break;
568            }
569
570            mDeferredActions.push_back(
571                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
572                                           FLUSH_CMD_SHUTDOWN /* video */));
573
574            mDeferredActions.push_back(
575                    new SetSurfaceAction(
576                        static_cast<NativeWindowWrapper *>(obj.get())));
577
578            if (obj != NULL) {
579                if (mStarted) {
580                    // Issue a seek to refresh the video screen only if started otherwise
581                    // the extractor may not yet be started and will assert.
582                    // If the video decoder is not set (perhaps audio only in this case)
583                    // do not perform a seek as it is not needed.
584                    int64_t currentPositionUs = 0;
585                    if (getCurrentPosition(&currentPositionUs) == OK) {
586                        mDeferredActions.push_back(
587                                new SeekAction(currentPositionUs, false /* needNotify */));
588                    }
589                }
590
591                // If there is a new surface texture, instantiate decoders
592                // again if possible.
593                mDeferredActions.push_back(
594                        new SimpleAction(&NuPlayer::performScanSources));
595            }
596
597            // After a flush without shutdown, decoder is paused.
598            // Don't resume it until source seek is done, otherwise it could
599            // start pulling stale data too soon.
600            mDeferredActions.push_back(
601                    new ResumeDecoderAction(false /* needNotify */));
602
603            processDeferredActions();
604            break;
605        }
606
607        case kWhatSetAudioSink:
608        {
609            ALOGV("kWhatSetAudioSink");
610
611            sp<RefBase> obj;
612            CHECK(msg->findObject("sink", &obj));
613
614            mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
615            break;
616        }
617
618        case kWhatStart:
619        {
620            ALOGV("kWhatStart");
621            if (mStarted) {
622                onResume();
623            } else {
624                onStart();
625            }
626            mPausedByClient = false;
627            break;
628        }
629
630        case kWhatSetRate:
631        {
632            ALOGV("kWhatSetRate");
633            CHECK(msg->findFloat("rate", &mPlaybackRate));
634            if (mRenderer != NULL) {
635                mRenderer->setPlaybackRate(mPlaybackRate);
636            }
637            break;
638        }
639
640        case kWhatScanSources:
641        {
642            int32_t generation;
643            CHECK(msg->findInt32("generation", &generation));
644            if (generation != mScanSourcesGeneration) {
645                // Drop obsolete msg.
646                break;
647            }
648
649            mScanSourcesPending = false;
650
651            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
652                 mAudioDecoder != NULL, mVideoDecoder != NULL);
653
654            bool mHadAnySourcesBefore =
655                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
656
657            // initialize video before audio because successful initialization of
658            // video may change deep buffer mode of audio.
659            if (mNativeWindow != NULL) {
660                instantiateDecoder(false, &mVideoDecoder);
661            }
662
663            // Don't try to re-open audio sink if there's an existing decoder.
664            if (mAudioSink != NULL && mAudioDecoder == NULL) {
665                sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
666                sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
667                audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
668                const bool hasVideo = (videoFormat != NULL);
669                const bool canOffload = canOffloadStream(
670                        audioMeta, hasVideo, true /* is_streaming */, streamType);
671                if (canOffload) {
672                    if (!mOffloadAudio) {
673                        mRenderer->signalEnableOffloadAudio();
674                    }
675                    // open audio sink early under offload mode.
676                    sp<AMessage> format = mSource->getFormat(true /*audio*/);
677                    tryOpenAudioSinkForOffload(format, hasVideo);
678                }
679                instantiateDecoder(true, &mAudioDecoder);
680            }
681
682            if (!mHadAnySourcesBefore
683                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
684                // This is the first time we've found anything playable.
685
686                if (mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
687                    schedulePollDuration();
688                }
689            }
690
691            status_t err;
692            if ((err = mSource->feedMoreTSData()) != OK) {
693                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
694                    // We're not currently decoding anything (no audio or
695                    // video tracks found) and we just ran out of input data.
696
697                    if (err == ERROR_END_OF_STREAM) {
698                        notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
699                    } else {
700                        notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
701                    }
702                }
703                break;
704            }
705
706            if ((mAudioDecoder == NULL && mAudioSink != NULL)
707                    || (mVideoDecoder == NULL && mNativeWindow != NULL)) {
708                msg->post(100000ll);
709                mScanSourcesPending = true;
710            }
711            break;
712        }
713
714        case kWhatVideoNotify:
715        case kWhatAudioNotify:
716        {
717            bool audio = msg->what() == kWhatAudioNotify;
718
719            int32_t currentDecoderGeneration =
720                (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
721            int32_t requesterGeneration = currentDecoderGeneration - 1;
722            CHECK(msg->findInt32("generation", &requesterGeneration));
723
724            if (requesterGeneration != currentDecoderGeneration) {
725                ALOGV("got message from old %s decoder, generation(%d:%d)",
726                        audio ? "audio" : "video", requesterGeneration,
727                        currentDecoderGeneration);
728                sp<AMessage> reply;
729                if (!(msg->findMessage("reply", &reply))) {
730                    return;
731                }
732
733                reply->setInt32("err", INFO_DISCONTINUITY);
734                reply->post();
735                return;
736            }
737
738            int32_t what;
739            CHECK(msg->findInt32("what", &what));
740
741            if (what == DecoderBase::kWhatInputDiscontinuity) {
742                int32_t formatChange;
743                CHECK(msg->findInt32("formatChange", &formatChange));
744
745                ALOGV("%s discontinuity: formatChange %d",
746                        audio ? "audio" : "video", formatChange);
747
748                if (formatChange) {
749                    mDeferredActions.push_back(
750                            new FlushDecoderAction(
751                                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
752                                audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
753                }
754
755                mDeferredActions.push_back(
756                        new SimpleAction(
757                                &NuPlayer::performScanSources));
758
759                processDeferredActions();
760            } else if (what == DecoderBase::kWhatEOS) {
761                int32_t err;
762                CHECK(msg->findInt32("err", &err));
763
764                if (err == ERROR_END_OF_STREAM) {
765                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
766                } else {
767                    ALOGV("got %s decoder EOS w/ error %d",
768                         audio ? "audio" : "video",
769                         err);
770                }
771
772                mRenderer->queueEOS(audio, err);
773            } else if (what == DecoderBase::kWhatFlushCompleted) {
774                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
775
776                handleFlushComplete(audio, true /* isDecoder */);
777                finishFlushIfPossible();
778            } else if (what == DecoderBase::kWhatVideoSizeChanged) {
779                sp<AMessage> format;
780                CHECK(msg->findMessage("format", &format));
781
782                sp<AMessage> inputFormat =
783                        mSource->getFormat(false /* audio */);
784
785                updateVideoSize(inputFormat, format);
786            } else if (what == DecoderBase::kWhatShutdownCompleted) {
787                ALOGV("%s shutdown completed", audio ? "audio" : "video");
788                if (audio) {
789                    mAudioDecoder.clear();
790                    ++mAudioDecoderGeneration;
791
792                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
793                    mFlushingAudio = SHUT_DOWN;
794                } else {
795                    mVideoDecoder.clear();
796                    ++mVideoDecoderGeneration;
797
798                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
799                    mFlushingVideo = SHUT_DOWN;
800                }
801
802                finishFlushIfPossible();
803            } else if (what == DecoderBase::kWhatResumeCompleted) {
804                finishResume();
805            } else if (what == DecoderBase::kWhatError) {
806                status_t err;
807                if (!msg->findInt32("err", &err) || err == OK) {
808                    err = UNKNOWN_ERROR;
809                }
810
811                // Decoder errors can be due to Source (e.g. from streaming),
812                // or from decoding corrupted bitstreams, or from other decoder
813                // MediaCodec operations (e.g. from an ongoing reset or seek).
814                // They may also be due to openAudioSink failure at
815                // decoder start or after a format change.
816                //
817                // We try to gracefully shut down the affected decoder if possible,
818                // rather than trying to force the shutdown with something
819                // similar to performReset(). This method can lead to a hang
820                // if MediaCodec functions block after an error, but they should
821                // typically return INVALID_OPERATION instead of blocking.
822
823                FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
824                ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
825                        err, audio ? "audio" : "video", *flushing);
826
827                switch (*flushing) {
828                    case NONE:
829                        mDeferredActions.push_back(
830                                new FlushDecoderAction(
831                                    audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
832                                    audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
833                        processDeferredActions();
834                        break;
835                    case FLUSHING_DECODER:
836                        *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
837                        break; // Wait for flush to complete.
838                    case FLUSHING_DECODER_SHUTDOWN:
839                        break; // Wait for flush to complete.
840                    case SHUTTING_DOWN_DECODER:
841                        break; // Wait for shutdown to complete.
842                    case FLUSHED:
843                        // Widevine source reads must stop before releasing the video decoder.
844                        if (!audio && mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
845                            mSource->stop();
846                        }
847                        getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
848                        *flushing = SHUTTING_DOWN_DECODER;     // Shut down.
849                        break;
850                    case SHUT_DOWN:
851                        finishFlushIfPossible();  // Should not occur.
852                        break;                    // Finish anyways.
853                }
854                notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
855            } else {
856                ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
857                      what,
858                      what >> 24,
859                      (what >> 16) & 0xff,
860                      (what >> 8) & 0xff,
861                      what & 0xff);
862            }
863
864            break;
865        }
866
867        case kWhatRendererNotify:
868        {
869            int32_t requesterGeneration = mRendererGeneration - 1;
870            CHECK(msg->findInt32("generation", &requesterGeneration));
871            if (requesterGeneration != mRendererGeneration) {
872                ALOGV("got message from old renderer, generation(%d:%d)",
873                        requesterGeneration, mRendererGeneration);
874                return;
875            }
876
877            int32_t what;
878            CHECK(msg->findInt32("what", &what));
879
880            if (what == Renderer::kWhatEOS) {
881                int32_t audio;
882                CHECK(msg->findInt32("audio", &audio));
883
884                int32_t finalResult;
885                CHECK(msg->findInt32("finalResult", &finalResult));
886
887                if (audio) {
888                    mAudioEOS = true;
889                } else {
890                    mVideoEOS = true;
891                }
892
893                if (finalResult == ERROR_END_OF_STREAM) {
894                    ALOGV("reached %s EOS", audio ? "audio" : "video");
895                } else {
896                    ALOGE("%s track encountered an error (%d)",
897                         audio ? "audio" : "video", finalResult);
898
899                    notifyListener(
900                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
901                }
902
903                if ((mAudioEOS || mAudioDecoder == NULL)
904                        && (mVideoEOS || mVideoDecoder == NULL)) {
905                    notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
906                }
907            } else if (what == Renderer::kWhatFlushComplete) {
908                int32_t audio;
909                CHECK(msg->findInt32("audio", &audio));
910
911                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
912                handleFlushComplete(audio, false /* isDecoder */);
913                finishFlushIfPossible();
914            } else if (what == Renderer::kWhatVideoRenderingStart) {
915                notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0);
916            } else if (what == Renderer::kWhatMediaRenderingStart) {
917                ALOGV("media rendering started");
918                notifyListener(MEDIA_STARTED, 0, 0);
919            } else if (what == Renderer::kWhatAudioOffloadTearDown) {
920                ALOGV("Tear down audio offload, fall back to s/w path if due to error.");
921                int64_t positionUs;
922                CHECK(msg->findInt64("positionUs", &positionUs));
923                int32_t reason;
924                CHECK(msg->findInt32("reason", &reason));
925                closeAudioSink();
926                mAudioDecoder.clear();
927                ++mAudioDecoderGeneration;
928                mRenderer->flush(
929                        true /* audio */, false /* notifyComplete */);
930                if (mVideoDecoder != NULL) {
931                    mRenderer->flush(
932                            false /* audio */, false /* notifyComplete */);
933                }
934
935                performSeek(positionUs, false /* needNotify */);
936                if (reason == Renderer::kDueToError) {
937                    mRenderer->signalDisableOffloadAudio();
938                    mOffloadAudio = false;
939                    instantiateDecoder(true /* audio */, &mAudioDecoder);
940                }
941            }
942            break;
943        }
944
945        case kWhatMoreDataQueued:
946        {
947            break;
948        }
949
950        case kWhatReset:
951        {
952            ALOGV("kWhatReset");
953
954            mDeferredActions.push_back(
955                    new FlushDecoderAction(
956                        FLUSH_CMD_SHUTDOWN /* audio */,
957                        FLUSH_CMD_SHUTDOWN /* video */));
958
959            mDeferredActions.push_back(
960                    new SimpleAction(&NuPlayer::performReset));
961
962            processDeferredActions();
963            break;
964        }
965
966        case kWhatSeek:
967        {
968            int64_t seekTimeUs;
969            int32_t needNotify;
970            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
971            CHECK(msg->findInt32("needNotify", &needNotify));
972
973            ALOGV("kWhatSeek seekTimeUs=%lld us, needNotify=%d",
974                    seekTimeUs, needNotify);
975
976            mDeferredActions.push_back(
977                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
978                                           FLUSH_CMD_FLUSH /* video */));
979
980            mDeferredActions.push_back(
981                    new SeekAction(seekTimeUs, needNotify));
982
983            // After a flush without shutdown, decoder is paused.
984            // Don't resume it until source seek is done, otherwise it could
985            // start pulling stale data too soon.
986            mDeferredActions.push_back(
987                    new ResumeDecoderAction(needNotify));
988
989            processDeferredActions();
990            break;
991        }
992
993        case kWhatPause:
994        {
995            onPause();
996            mPausedByClient = true;
997            break;
998        }
999
1000        case kWhatSourceNotify:
1001        {
1002            onSourceNotify(msg);
1003            break;
1004        }
1005
1006        case kWhatClosedCaptionNotify:
1007        {
1008            onClosedCaptionNotify(msg);
1009            break;
1010        }
1011
1012        default:
1013            TRESPASS();
1014            break;
1015    }
1016}
1017
1018void NuPlayer::onResume() {
1019    if (!mPaused) {
1020        return;
1021    }
1022    mPaused = false;
1023    if (mSource != NULL) {
1024        mSource->resume();
1025    } else {
1026        ALOGW("resume called when source is gone or not set");
1027    }
1028    // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
1029    // needed.
1030    if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
1031        instantiateDecoder(true /* audio */, &mAudioDecoder);
1032    }
1033    if (mRenderer != NULL) {
1034        mRenderer->resume();
1035    } else {
1036        ALOGW("resume called when renderer is gone or not set");
1037    }
1038}
1039
1040status_t NuPlayer::onInstantiateSecureDecoders() {
1041    status_t err;
1042    if (!(mSourceFlags & Source::FLAG_SECURE)) {
1043        return BAD_TYPE;
1044    }
1045
1046    if (mRenderer != NULL) {
1047        ALOGE("renderer should not be set when instantiating secure decoders");
1048        return UNKNOWN_ERROR;
1049    }
1050
1051    // TRICKY: We rely on mRenderer being null, so that decoder does not start requesting
1052    // data on instantiation.
1053    if (mNativeWindow != NULL) {
1054        err = instantiateDecoder(false, &mVideoDecoder);
1055        if (err != OK) {
1056            return err;
1057        }
1058    }
1059
1060    if (mAudioSink != NULL) {
1061        err = instantiateDecoder(true, &mAudioDecoder);
1062        if (err != OK) {
1063            return err;
1064        }
1065    }
1066    return OK;
1067}
1068
1069void NuPlayer::onStart() {
1070    mOffloadAudio = false;
1071    mAudioEOS = false;
1072    mVideoEOS = false;
1073    mStarted = true;
1074
1075    mSource->start();
1076
1077    uint32_t flags = 0;
1078
1079    if (mSource->isRealTime()) {
1080        flags |= Renderer::FLAG_REAL_TIME;
1081    }
1082
1083    sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
1084    audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
1085    if (mAudioSink != NULL) {
1086        streamType = mAudioSink->getAudioStreamType();
1087    }
1088
1089    sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
1090
1091    mOffloadAudio =
1092        canOffloadStream(audioMeta, (videoFormat != NULL),
1093                         true /* is_streaming */, streamType);
1094    if (mOffloadAudio) {
1095        flags |= Renderer::FLAG_OFFLOAD_AUDIO;
1096    }
1097
1098    sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
1099    ++mRendererGeneration;
1100    notify->setInt32("generation", mRendererGeneration);
1101    mRenderer = new Renderer(mAudioSink, notify, flags);
1102    mRendererLooper = new ALooper;
1103    mRendererLooper->setName("NuPlayerRenderer");
1104    mRendererLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1105    mRendererLooper->registerHandler(mRenderer);
1106    if (mPlaybackRate != 1.0) {
1107        mRenderer->setPlaybackRate(mPlaybackRate);
1108    }
1109
1110    sp<MetaData> meta = getFileMeta();
1111    int32_t rate;
1112    if (meta != NULL
1113            && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
1114        mRenderer->setVideoFrameRate(rate);
1115    }
1116
1117    if (mVideoDecoder != NULL) {
1118        mVideoDecoder->setRenderer(mRenderer);
1119    }
1120    if (mAudioDecoder != NULL) {
1121        mAudioDecoder->setRenderer(mRenderer);
1122    }
1123
1124    postScanSources();
1125}
1126
1127void NuPlayer::onPause() {
1128    if (mPaused) {
1129        return;
1130    }
1131    mPaused = true;
1132    if (mSource != NULL) {
1133        mSource->pause();
1134    } else {
1135        ALOGW("pause called when source is gone or not set");
1136    }
1137    if (mRenderer != NULL) {
1138        mRenderer->pause();
1139    } else {
1140        ALOGW("pause called when renderer is gone or not set");
1141    }
1142}
1143
1144bool NuPlayer::audioDecoderStillNeeded() {
1145    // Audio decoder is no longer needed if it's in shut/shutting down status.
1146    return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
1147}
1148
1149void NuPlayer::handleFlushComplete(bool audio, bool isDecoder) {
1150    // We wait for both the decoder flush and the renderer flush to complete
1151    // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
1152
1153    mFlushComplete[audio][isDecoder] = true;
1154    if (!mFlushComplete[audio][!isDecoder]) {
1155        return;
1156    }
1157
1158    FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
1159    switch (*state) {
1160        case FLUSHING_DECODER:
1161        {
1162            *state = FLUSHED;
1163            break;
1164        }
1165
1166        case FLUSHING_DECODER_SHUTDOWN:
1167        {
1168            *state = SHUTTING_DOWN_DECODER;
1169
1170            ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
1171            if (!audio) {
1172                // Widevine source reads must stop before releasing the video decoder.
1173                if (mSource != NULL && mSourceFlags & Source::FLAG_SECURE) {
1174                    mSource->stop();
1175                }
1176            }
1177            getDecoder(audio)->initiateShutdown();
1178            break;
1179        }
1180
1181        default:
1182            // decoder flush completes only occur in a flushing state.
1183            LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
1184            break;
1185    }
1186}
1187
1188void NuPlayer::finishFlushIfPossible() {
1189    if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
1190            && mFlushingAudio != SHUT_DOWN) {
1191        return;
1192    }
1193
1194    if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
1195            && mFlushingVideo != SHUT_DOWN) {
1196        return;
1197    }
1198
1199    ALOGV("both audio and video are flushed now.");
1200
1201    mFlushingAudio = NONE;
1202    mFlushingVideo = NONE;
1203
1204    clearFlushComplete();
1205
1206    processDeferredActions();
1207}
1208
1209void NuPlayer::postScanSources() {
1210    if (mScanSourcesPending) {
1211        return;
1212    }
1213
1214    sp<AMessage> msg = new AMessage(kWhatScanSources, this);
1215    msg->setInt32("generation", mScanSourcesGeneration);
1216    msg->post();
1217
1218    mScanSourcesPending = true;
1219}
1220
1221void NuPlayer::tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo) {
1222    // Note: This is called early in NuPlayer to determine whether offloading
1223    // is possible; otherwise the decoders call the renderer openAudioSink directly.
1224
1225    status_t err = mRenderer->openAudioSink(
1226            format, true /* offloadOnly */, hasVideo, AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio);
1227    if (err != OK) {
1228        // Any failure we turn off mOffloadAudio.
1229        mOffloadAudio = false;
1230    } else if (mOffloadAudio) {
1231        sp<MetaData> audioMeta =
1232                mSource->getFormatMeta(true /* audio */);
1233        sendMetaDataToHal(mAudioSink, audioMeta);
1234    }
1235}
1236
1237void NuPlayer::closeAudioSink() {
1238    mRenderer->closeAudioSink();
1239}
1240
1241status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
1242    if (*decoder != NULL) {
1243        return OK;
1244    }
1245
1246    sp<AMessage> format = mSource->getFormat(audio);
1247
1248    if (format == NULL) {
1249        return -EWOULDBLOCK;
1250    }
1251
1252    if (!audio) {
1253        AString mime;
1254        CHECK(format->findString("mime", &mime));
1255
1256        sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
1257        if (mCCDecoder == NULL) {
1258            mCCDecoder = new CCDecoder(ccNotify);
1259        }
1260
1261        if (mSourceFlags & Source::FLAG_SECURE) {
1262            format->setInt32("secure", true);
1263        }
1264
1265        if (mSourceFlags & Source::FLAG_PROTECTED) {
1266            format->setInt32("protected", true);
1267        }
1268    }
1269
1270    if (audio) {
1271        sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
1272        ++mAudioDecoderGeneration;
1273        notify->setInt32("generation", mAudioDecoderGeneration);
1274
1275        if (mOffloadAudio) {
1276            const bool hasVideo = (mSource->getFormat(false /*audio */) != NULL);
1277            format->setInt32("has-video", hasVideo);
1278            *decoder = new DecoderPassThrough(notify, mSource, mRenderer);
1279        } else {
1280            *decoder = new Decoder(notify, mSource, mRenderer);
1281        }
1282    } else {
1283        sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
1284        ++mVideoDecoderGeneration;
1285        notify->setInt32("generation", mVideoDecoderGeneration);
1286
1287        *decoder = new Decoder(
1288                notify, mSource, mRenderer, mNativeWindow, mCCDecoder);
1289
1290        // enable FRC if high-quality AV sync is requested, even if not
1291        // queuing to native window, as this will even improve textureview
1292        // playback.
1293        {
1294            char value[PROPERTY_VALUE_MAX];
1295            if (property_get("persist.sys.media.avsync", value, NULL) &&
1296                    (!strcmp("1", value) || !strcasecmp("true", value))) {
1297                format->setInt32("auto-frc", 1);
1298            }
1299        }
1300    }
1301    (*decoder)->init();
1302    (*decoder)->configure(format);
1303
1304    // allocate buffers to decrypt widevine source buffers
1305    if (!audio && (mSourceFlags & Source::FLAG_SECURE)) {
1306        Vector<sp<ABuffer> > inputBufs;
1307        CHECK_EQ((*decoder)->getInputBuffers(&inputBufs), (status_t)OK);
1308
1309        Vector<MediaBuffer *> mediaBufs;
1310        for (size_t i = 0; i < inputBufs.size(); i++) {
1311            const sp<ABuffer> &buffer = inputBufs[i];
1312            MediaBuffer *mbuf = new MediaBuffer(buffer->data(), buffer->size());
1313            mediaBufs.push(mbuf);
1314        }
1315
1316        status_t err = mSource->setBuffers(audio, mediaBufs);
1317        if (err != OK) {
1318            for (size_t i = 0; i < mediaBufs.size(); ++i) {
1319                mediaBufs[i]->release();
1320            }
1321            mediaBufs.clear();
1322            ALOGE("Secure source didn't support secure mediaBufs.");
1323            return err;
1324        }
1325    }
1326    return OK;
1327}
1328
1329void NuPlayer::updateVideoSize(
1330        const sp<AMessage> &inputFormat,
1331        const sp<AMessage> &outputFormat) {
1332    if (inputFormat == NULL) {
1333        ALOGW("Unknown video size, reporting 0x0!");
1334        notifyListener(MEDIA_SET_VIDEO_SIZE, 0, 0);
1335        return;
1336    }
1337
1338    int32_t displayWidth, displayHeight;
1339    int32_t cropLeft, cropTop, cropRight, cropBottom;
1340
1341    if (outputFormat != NULL) {
1342        int32_t width, height;
1343        CHECK(outputFormat->findInt32("width", &width));
1344        CHECK(outputFormat->findInt32("height", &height));
1345
1346        int32_t cropLeft, cropTop, cropRight, cropBottom;
1347        CHECK(outputFormat->findRect(
1348                    "crop",
1349                    &cropLeft, &cropTop, &cropRight, &cropBottom));
1350
1351        displayWidth = cropRight - cropLeft + 1;
1352        displayHeight = cropBottom - cropTop + 1;
1353
1354        ALOGV("Video output format changed to %d x %d "
1355             "(crop: %d x %d @ (%d, %d))",
1356             width, height,
1357             displayWidth,
1358             displayHeight,
1359             cropLeft, cropTop);
1360    } else {
1361        CHECK(inputFormat->findInt32("width", &displayWidth));
1362        CHECK(inputFormat->findInt32("height", &displayHeight));
1363
1364        ALOGV("Video input format %d x %d", displayWidth, displayHeight);
1365    }
1366
1367    // Take into account sample aspect ratio if necessary:
1368    int32_t sarWidth, sarHeight;
1369    if (inputFormat->findInt32("sar-width", &sarWidth)
1370            && inputFormat->findInt32("sar-height", &sarHeight)) {
1371        ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
1372
1373        displayWidth = (displayWidth * sarWidth) / sarHeight;
1374
1375        ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
1376    }
1377
1378    int32_t rotationDegrees;
1379    if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
1380        rotationDegrees = 0;
1381    }
1382
1383    if (rotationDegrees == 90 || rotationDegrees == 270) {
1384        int32_t tmp = displayWidth;
1385        displayWidth = displayHeight;
1386        displayHeight = tmp;
1387    }
1388
1389    notifyListener(
1390            MEDIA_SET_VIDEO_SIZE,
1391            displayWidth,
1392            displayHeight);
1393}
1394
1395void NuPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *in) {
1396    if (mDriver == NULL) {
1397        return;
1398    }
1399
1400    sp<NuPlayerDriver> driver = mDriver.promote();
1401
1402    if (driver == NULL) {
1403        return;
1404    }
1405
1406    driver->notifyListener(msg, ext1, ext2, in);
1407}
1408
1409void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
1410    ALOGV("[%s] flushDecoder needShutdown=%d",
1411          audio ? "audio" : "video", needShutdown);
1412
1413    const sp<DecoderBase> &decoder = getDecoder(audio);
1414    if (decoder == NULL) {
1415        ALOGI("flushDecoder %s without decoder present",
1416             audio ? "audio" : "video");
1417        return;
1418    }
1419
1420    // Make sure we don't continue to scan sources until we finish flushing.
1421    ++mScanSourcesGeneration;
1422    if (mScanSourcesPending) {
1423        mDeferredActions.push_back(
1424                new SimpleAction(&NuPlayer::performScanSources));
1425        mScanSourcesPending = false;
1426    }
1427
1428    decoder->signalFlush();
1429
1430    FlushStatus newStatus =
1431        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
1432
1433    mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
1434    mFlushComplete[audio][true /* isDecoder */] = false;
1435    if (audio) {
1436        ALOGE_IF(mFlushingAudio != NONE,
1437                "audio flushDecoder() is called in state %d", mFlushingAudio);
1438        mFlushingAudio = newStatus;
1439    } else {
1440        ALOGE_IF(mFlushingVideo != NONE,
1441                "video flushDecoder() is called in state %d", mFlushingVideo);
1442        mFlushingVideo = newStatus;
1443    }
1444}
1445
1446void NuPlayer::queueDecoderShutdown(
1447        bool audio, bool video, const sp<AMessage> &reply) {
1448    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
1449
1450    mDeferredActions.push_back(
1451            new FlushDecoderAction(
1452                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
1453                video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
1454
1455    mDeferredActions.push_back(
1456            new SimpleAction(&NuPlayer::performScanSources));
1457
1458    mDeferredActions.push_back(new PostMessageAction(reply));
1459
1460    processDeferredActions();
1461}
1462
1463status_t NuPlayer::setVideoScalingMode(int32_t mode) {
1464    mVideoScalingMode = mode;
1465    if (mNativeWindow != NULL) {
1466        status_t ret = native_window_set_scaling_mode(
1467                mNativeWindow->getNativeWindow().get(), mVideoScalingMode);
1468        if (ret != OK) {
1469            ALOGE("Failed to set scaling mode (%d): %s",
1470                -ret, strerror(-ret));
1471            return ret;
1472        }
1473    }
1474    return OK;
1475}
1476
1477status_t NuPlayer::getTrackInfo(Parcel* reply) const {
1478    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
1479    msg->setPointer("reply", reply);
1480
1481    sp<AMessage> response;
1482    status_t err = msg->postAndAwaitResponse(&response);
1483    return err;
1484}
1485
1486status_t NuPlayer::getSelectedTrack(int32_t type, Parcel* reply) const {
1487    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
1488    msg->setPointer("reply", reply);
1489    msg->setInt32("type", type);
1490
1491    sp<AMessage> response;
1492    status_t err = msg->postAndAwaitResponse(&response);
1493    if (err == OK && response != NULL) {
1494        CHECK(response->findInt32("err", &err));
1495    }
1496    return err;
1497}
1498
1499status_t NuPlayer::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
1500    sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
1501    msg->setSize("trackIndex", trackIndex);
1502    msg->setInt32("select", select);
1503    msg->setInt64("timeUs", timeUs);
1504
1505    sp<AMessage> response;
1506    status_t err = msg->postAndAwaitResponse(&response);
1507
1508    if (err != OK) {
1509        return err;
1510    }
1511
1512    if (!response->findInt32("err", &err)) {
1513        err = OK;
1514    }
1515
1516    return err;
1517}
1518
1519status_t NuPlayer::getCurrentPosition(int64_t *mediaUs) {
1520    sp<Renderer> renderer = mRenderer;
1521    if (renderer == NULL) {
1522        return NO_INIT;
1523    }
1524
1525    return renderer->getCurrentPosition(mediaUs);
1526}
1527
1528void NuPlayer::getStats(int64_t *numFramesTotal, int64_t *numFramesDropped) {
1529    sp<DecoderBase> decoder = getDecoder(false /* audio */);
1530    if (decoder != NULL) {
1531        decoder->getStats(numFramesTotal, numFramesDropped);
1532    } else {
1533        *numFramesTotal = 0;
1534        *numFramesDropped = 0;
1535    }
1536}
1537
1538sp<MetaData> NuPlayer::getFileMeta() {
1539    return mSource->getFileFormatMeta();
1540}
1541
1542void NuPlayer::schedulePollDuration() {
1543    sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
1544    msg->setInt32("generation", mPollDurationGeneration);
1545    msg->post();
1546}
1547
1548void NuPlayer::cancelPollDuration() {
1549    ++mPollDurationGeneration;
1550}
1551
1552void NuPlayer::processDeferredActions() {
1553    while (!mDeferredActions.empty()) {
1554        // We won't execute any deferred actions until we're no longer in
1555        // an intermediate state, i.e. one more more decoders are currently
1556        // flushing or shutting down.
1557
1558        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
1559            // We're currently flushing, postpone the reset until that's
1560            // completed.
1561
1562            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
1563                  mFlushingAudio, mFlushingVideo);
1564
1565            break;
1566        }
1567
1568        sp<Action> action = *mDeferredActions.begin();
1569        mDeferredActions.erase(mDeferredActions.begin());
1570
1571        action->execute(this);
1572    }
1573}
1574
1575void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
1576    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), needNotify(%d)",
1577          seekTimeUs,
1578          seekTimeUs / 1E6,
1579          needNotify);
1580
1581    if (mSource == NULL) {
1582        // This happens when reset occurs right before the loop mode
1583        // asynchronously seeks to the start of the stream.
1584        LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
1585                "mSource is NULL and decoders not NULL audio(%p) video(%p)",
1586                mAudioDecoder.get(), mVideoDecoder.get());
1587        return;
1588    }
1589    mSource->seekTo(seekTimeUs);
1590    ++mTimedTextGeneration;
1591
1592    // everything's flushed, continue playback.
1593}
1594
1595void NuPlayer::performDecoderFlush(FlushCommand audio, FlushCommand video) {
1596    ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
1597
1598    if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
1599            && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
1600        return;
1601    }
1602
1603    if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
1604        flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
1605    }
1606
1607    if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
1608        flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
1609    }
1610}
1611
1612void NuPlayer::performReset() {
1613    ALOGV("performReset");
1614
1615    CHECK(mAudioDecoder == NULL);
1616    CHECK(mVideoDecoder == NULL);
1617
1618    cancelPollDuration();
1619
1620    ++mScanSourcesGeneration;
1621    mScanSourcesPending = false;
1622
1623    if (mRendererLooper != NULL) {
1624        if (mRenderer != NULL) {
1625            mRendererLooper->unregisterHandler(mRenderer->id());
1626        }
1627        mRendererLooper->stop();
1628        mRendererLooper.clear();
1629    }
1630    mRenderer.clear();
1631    ++mRendererGeneration;
1632
1633    if (mSource != NULL) {
1634        mSource->stop();
1635
1636        mSource.clear();
1637    }
1638
1639    if (mDriver != NULL) {
1640        sp<NuPlayerDriver> driver = mDriver.promote();
1641        if (driver != NULL) {
1642            driver->notifyResetComplete();
1643        }
1644    }
1645
1646    mStarted = false;
1647}
1648
1649void NuPlayer::performScanSources() {
1650    ALOGV("performScanSources");
1651
1652    if (!mStarted) {
1653        return;
1654    }
1655
1656    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
1657        postScanSources();
1658    }
1659}
1660
1661void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
1662    ALOGV("performSetSurface");
1663
1664    mNativeWindow = wrapper;
1665
1666    // XXX - ignore error from setVideoScalingMode for now
1667    setVideoScalingMode(mVideoScalingMode);
1668
1669    if (mDriver != NULL) {
1670        sp<NuPlayerDriver> driver = mDriver.promote();
1671        if (driver != NULL) {
1672            driver->notifySetSurfaceComplete();
1673        }
1674    }
1675}
1676
1677void NuPlayer::performResumeDecoders(bool needNotify) {
1678    if (needNotify) {
1679        mResumePending = true;
1680        if (mVideoDecoder == NULL) {
1681            // if audio-only, we can notify seek complete now,
1682            // as the resume operation will be relatively fast.
1683            finishResume();
1684        }
1685    }
1686
1687    if (mVideoDecoder != NULL) {
1688        // When there is continuous seek, MediaPlayer will cache the seek
1689        // position, and send down new seek request when previous seek is
1690        // complete. Let's wait for at least one video output frame before
1691        // notifying seek complete, so that the video thumbnail gets updated
1692        // when seekbar is dragged.
1693        mVideoDecoder->signalResume(needNotify);
1694    }
1695
1696    if (mAudioDecoder != NULL) {
1697        mAudioDecoder->signalResume(false /* needNotify */);
1698    }
1699}
1700
1701void NuPlayer::finishResume() {
1702    if (mResumePending) {
1703        mResumePending = false;
1704        if (mDriver != NULL) {
1705            sp<NuPlayerDriver> driver = mDriver.promote();
1706            if (driver != NULL) {
1707                driver->notifySeekComplete();
1708            }
1709        }
1710    }
1711}
1712
1713void NuPlayer::onSourceNotify(const sp<AMessage> &msg) {
1714    int32_t what;
1715    CHECK(msg->findInt32("what", &what));
1716
1717    switch (what) {
1718        case Source::kWhatInstantiateSecureDecoders:
1719        {
1720            if (mSource == NULL) {
1721                // This is a stale notification from a source that was
1722                // asynchronously preparing when the client called reset().
1723                // We handled the reset, the source is gone.
1724                break;
1725            }
1726
1727            sp<AMessage> reply;
1728            CHECK(msg->findMessage("reply", &reply));
1729            status_t err = onInstantiateSecureDecoders();
1730            reply->setInt32("err", err);
1731            reply->post();
1732            break;
1733        }
1734
1735        case Source::kWhatPrepared:
1736        {
1737            if (mSource == NULL) {
1738                // This is a stale notification from a source that was
1739                // asynchronously preparing when the client called reset().
1740                // We handled the reset, the source is gone.
1741                break;
1742            }
1743
1744            int32_t err;
1745            CHECK(msg->findInt32("err", &err));
1746
1747            if (err != OK) {
1748                // shut down potential secure codecs in case client never calls reset
1749                mDeferredActions.push_back(
1750                        new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
1751                                               FLUSH_CMD_SHUTDOWN /* video */));
1752                processDeferredActions();
1753            }
1754
1755            sp<NuPlayerDriver> driver = mDriver.promote();
1756            if (driver != NULL) {
1757                // notify duration first, so that it's definitely set when
1758                // the app received the "prepare complete" callback.
1759                int64_t durationUs;
1760                if (mSource->getDuration(&durationUs) == OK) {
1761                    driver->notifyDuration(durationUs);
1762                }
1763                driver->notifyPrepareCompleted(err);
1764            }
1765
1766            break;
1767        }
1768
1769        case Source::kWhatFlagsChanged:
1770        {
1771            uint32_t flags;
1772            CHECK(msg->findInt32("flags", (int32_t *)&flags));
1773
1774            sp<NuPlayerDriver> driver = mDriver.promote();
1775            if (driver != NULL) {
1776                if ((flags & NuPlayer::Source::FLAG_CAN_SEEK) == 0) {
1777                    driver->notifyListener(
1778                            MEDIA_INFO, MEDIA_INFO_NOT_SEEKABLE, 0);
1779                }
1780                driver->notifyFlagsChanged(flags);
1781            }
1782
1783            if ((mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1784                    && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
1785                cancelPollDuration();
1786            } else if (!(mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
1787                    && (flags & Source::FLAG_DYNAMIC_DURATION)
1788                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
1789                schedulePollDuration();
1790            }
1791
1792            mSourceFlags = flags;
1793            break;
1794        }
1795
1796        case Source::kWhatVideoSizeChanged:
1797        {
1798            sp<AMessage> format;
1799            CHECK(msg->findMessage("format", &format));
1800
1801            updateVideoSize(format);
1802            break;
1803        }
1804
1805        case Source::kWhatBufferingUpdate:
1806        {
1807            int32_t percentage;
1808            CHECK(msg->findInt32("percentage", &percentage));
1809
1810            notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0);
1811            break;
1812        }
1813
1814        case Source::kWhatPauseOnBufferingStart:
1815        {
1816            // ignore if not playing
1817            if (mStarted && !mPausedByClient) {
1818                ALOGI("buffer low, pausing...");
1819
1820                onPause();
1821            }
1822            // fall-thru
1823        }
1824
1825        case Source::kWhatBufferingStart:
1826        {
1827            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
1828            break;
1829        }
1830
1831        case Source::kWhatResumeOnBufferingEnd:
1832        {
1833            // ignore if not playing
1834            if (mStarted && !mPausedByClient) {
1835                ALOGI("buffer ready, resuming...");
1836
1837                onResume();
1838            }
1839            // fall-thru
1840        }
1841
1842        case Source::kWhatBufferingEnd:
1843        {
1844            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
1845            break;
1846        }
1847
1848        case Source::kWhatCacheStats:
1849        {
1850            int32_t kbps;
1851            CHECK(msg->findInt32("bandwidth", &kbps));
1852
1853            notifyListener(MEDIA_INFO, MEDIA_INFO_NETWORK_BANDWIDTH, kbps);
1854            break;
1855        }
1856
1857        case Source::kWhatSubtitleData:
1858        {
1859            sp<ABuffer> buffer;
1860            CHECK(msg->findBuffer("buffer", &buffer));
1861
1862            sendSubtitleData(buffer, 0 /* baseIndex */);
1863            break;
1864        }
1865
1866        case Source::kWhatTimedMetaData:
1867        {
1868            sp<ABuffer> buffer;
1869            if (!msg->findBuffer("buffer", &buffer)) {
1870                notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
1871            } else {
1872                sendTimedMetaData(buffer);
1873            }
1874            break;
1875        }
1876
1877        case Source::kWhatTimedTextData:
1878        {
1879            int32_t generation;
1880            if (msg->findInt32("generation", &generation)
1881                    && generation != mTimedTextGeneration) {
1882                break;
1883            }
1884
1885            sp<ABuffer> buffer;
1886            CHECK(msg->findBuffer("buffer", &buffer));
1887
1888            sp<NuPlayerDriver> driver = mDriver.promote();
1889            if (driver == NULL) {
1890                break;
1891            }
1892
1893            int posMs;
1894            int64_t timeUs, posUs;
1895            driver->getCurrentPosition(&posMs);
1896            posUs = posMs * 1000;
1897            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1898
1899            if (posUs < timeUs) {
1900                if (!msg->findInt32("generation", &generation)) {
1901                    msg->setInt32("generation", mTimedTextGeneration);
1902                }
1903                msg->post(timeUs - posUs);
1904            } else {
1905                sendTimedTextData(buffer);
1906            }
1907            break;
1908        }
1909
1910        case Source::kWhatQueueDecoderShutdown:
1911        {
1912            int32_t audio, video;
1913            CHECK(msg->findInt32("audio", &audio));
1914            CHECK(msg->findInt32("video", &video));
1915
1916            sp<AMessage> reply;
1917            CHECK(msg->findMessage("reply", &reply));
1918
1919            queueDecoderShutdown(audio, video, reply);
1920            break;
1921        }
1922
1923        case Source::kWhatDrmNoLicense:
1924        {
1925            notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
1926            break;
1927        }
1928
1929        default:
1930            TRESPASS();
1931    }
1932}
1933
1934void NuPlayer::onClosedCaptionNotify(const sp<AMessage> &msg) {
1935    int32_t what;
1936    CHECK(msg->findInt32("what", &what));
1937
1938    switch (what) {
1939        case NuPlayer::CCDecoder::kWhatClosedCaptionData:
1940        {
1941            sp<ABuffer> buffer;
1942            CHECK(msg->findBuffer("buffer", &buffer));
1943
1944            size_t inbandTracks = 0;
1945            if (mSource != NULL) {
1946                inbandTracks = mSource->getTrackCount();
1947            }
1948
1949            sendSubtitleData(buffer, inbandTracks);
1950            break;
1951        }
1952
1953        case NuPlayer::CCDecoder::kWhatTrackAdded:
1954        {
1955            notifyListener(MEDIA_INFO, MEDIA_INFO_METADATA_UPDATE, 0);
1956
1957            break;
1958        }
1959
1960        default:
1961            TRESPASS();
1962    }
1963
1964
1965}
1966
1967void NuPlayer::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
1968    int32_t trackIndex;
1969    int64_t timeUs, durationUs;
1970    CHECK(buffer->meta()->findInt32("trackIndex", &trackIndex));
1971    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1972    CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
1973
1974    Parcel in;
1975    in.writeInt32(trackIndex + baseIndex);
1976    in.writeInt64(timeUs);
1977    in.writeInt64(durationUs);
1978    in.writeInt32(buffer->size());
1979    in.writeInt32(buffer->size());
1980    in.write(buffer->data(), buffer->size());
1981
1982    notifyListener(MEDIA_SUBTITLE_DATA, 0, 0, &in);
1983}
1984
1985void NuPlayer::sendTimedMetaData(const sp<ABuffer> &buffer) {
1986    int64_t timeUs;
1987    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1988
1989    Parcel in;
1990    in.writeInt64(timeUs);
1991    in.writeInt32(buffer->size());
1992    in.writeInt32(buffer->size());
1993    in.write(buffer->data(), buffer->size());
1994
1995    notifyListener(MEDIA_META_DATA, 0, 0, &in);
1996}
1997
1998void NuPlayer::sendTimedTextData(const sp<ABuffer> &buffer) {
1999    const void *data;
2000    size_t size = 0;
2001    int64_t timeUs;
2002    int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
2003
2004    AString mime;
2005    CHECK(buffer->meta()->findString("mime", &mime));
2006    CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
2007
2008    data = buffer->data();
2009    size = buffer->size();
2010
2011    Parcel parcel;
2012    if (size > 0) {
2013        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2014        flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
2015        TextDescriptions::getParcelOfDescriptions(
2016                (const uint8_t *)data, size, flag, timeUs / 1000, &parcel);
2017    }
2018
2019    if ((parcel.dataSize() > 0)) {
2020        notifyListener(MEDIA_TIMED_TEXT, 0, 0, &parcel);
2021    } else {  // send an empty timed text
2022        notifyListener(MEDIA_TIMED_TEXT, 0, 0);
2023    }
2024}
2025////////////////////////////////////////////////////////////////////////////////
2026
2027sp<AMessage> NuPlayer::Source::getFormat(bool audio) {
2028    sp<MetaData> meta = getFormatMeta(audio);
2029
2030    if (meta == NULL) {
2031        return NULL;
2032    }
2033
2034    sp<AMessage> msg = new AMessage;
2035
2036    if(convertMetaDataToMessage(meta, &msg) == OK) {
2037        return msg;
2038    }
2039    return NULL;
2040}
2041
2042void NuPlayer::Source::notifyFlagsChanged(uint32_t flags) {
2043    sp<AMessage> notify = dupNotify();
2044    notify->setInt32("what", kWhatFlagsChanged);
2045    notify->setInt32("flags", flags);
2046    notify->post();
2047}
2048
2049void NuPlayer::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
2050    sp<AMessage> notify = dupNotify();
2051    notify->setInt32("what", kWhatVideoSizeChanged);
2052    notify->setMessage("format", format);
2053    notify->post();
2054}
2055
2056void NuPlayer::Source::notifyPrepared(status_t err) {
2057    sp<AMessage> notify = dupNotify();
2058    notify->setInt32("what", kWhatPrepared);
2059    notify->setInt32("err", err);
2060    notify->post();
2061}
2062
2063void NuPlayer::Source::notifyInstantiateSecureDecoders(const sp<AMessage> &reply) {
2064    sp<AMessage> notify = dupNotify();
2065    notify->setInt32("what", kWhatInstantiateSecureDecoders);
2066    notify->setMessage("reply", reply);
2067    notify->post();
2068}
2069
2070void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
2071    TRESPASS();
2072}
2073
2074}  // namespace android
2075