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(¤tPositionUs) == 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