content/media/omx/MediaOmxDecoder.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rwxr-xr-x

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "MediaOmxDecoder.h"
michael@0 8 #include "MediaOmxReader.h"
michael@0 9 #include "MediaDecoderStateMachine.h"
michael@0 10
michael@0 11 #include "OmxDecoder.h"
michael@0 12
michael@0 13 #ifdef MOZ_AUDIO_OFFLOAD
michael@0 14 #include "AudioOffloadPlayer.h"
michael@0 15 #endif
michael@0 16
michael@0 17 using namespace android;
michael@0 18
michael@0 19 namespace mozilla {
michael@0 20
michael@0 21 #ifdef PR_LOGGING
michael@0 22 extern PRLogModuleInfo* gMediaDecoderLog;
michael@0 23 #define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
michael@0 24 #else
michael@0 25 #define DECODER_LOG(type, msg)
michael@0 26 #endif
michael@0 27
michael@0 28 MediaOmxDecoder::MediaOmxDecoder() :
michael@0 29 MediaDecoder(),
michael@0 30 mCanOffloadAudio(false),
michael@0 31 mFallbackToStateMachine(false)
michael@0 32 {
michael@0 33 #ifdef PR_LOGGING
michael@0 34 if (!gMediaDecoderLog) {
michael@0 35 gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
michael@0 36 }
michael@0 37 #endif
michael@0 38 }
michael@0 39
michael@0 40 MediaDecoder* MediaOmxDecoder::Clone()
michael@0 41 {
michael@0 42 return new MediaOmxDecoder();
michael@0 43 }
michael@0 44
michael@0 45 MediaDecoderStateMachine* MediaOmxDecoder::CreateStateMachine()
michael@0 46 {
michael@0 47 mReader = new MediaOmxReader(this);
michael@0 48 mReader->SetAudioChannel(GetAudioChannel());
michael@0 49 return new MediaDecoderStateMachine(this, mReader);
michael@0 50 }
michael@0 51
michael@0 52 void MediaOmxDecoder::SetCanOffloadAudio(bool aCanOffloadAudio)
michael@0 53 {
michael@0 54 ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
michael@0 55 mCanOffloadAudio = aCanOffloadAudio;
michael@0 56 }
michael@0 57
michael@0 58 void MediaOmxDecoder::MetadataLoaded(int aChannels,
michael@0 59 int aRate,
michael@0 60 bool aHasAudio,
michael@0 61 bool aHasVideo,
michael@0 62 MetadataTags* aTags)
michael@0 63 {
michael@0 64 MOZ_ASSERT(NS_IsMainThread());
michael@0 65 MediaDecoder::MetadataLoaded(aChannels, aRate, aHasAudio, aHasVideo, aTags);
michael@0 66
michael@0 67 ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
michael@0 68 if (!mCanOffloadAudio || mFallbackToStateMachine || mOutputStreams.Length() ||
michael@0 69 mInitialPlaybackRate != 1.0) {
michael@0 70 DECODER_LOG(PR_LOG_DEBUG, ("In %s Offload Audio check failed",
michael@0 71 __PRETTY_FUNCTION__));
michael@0 72 return;
michael@0 73 }
michael@0 74
michael@0 75 #ifdef MOZ_AUDIO_OFFLOAD
michael@0 76 mAudioOffloadPlayer = new AudioOffloadPlayer(this);
michael@0 77 #endif
michael@0 78 mAudioOffloadPlayer->SetSource(mReader->GetAudioOffloadTrack());
michael@0 79 status_t err = mAudioOffloadPlayer->Start(false);
michael@0 80 if (err == OK) {
michael@0 81 PauseStateMachine();
michael@0 82 // Call ChangeState() to run AudioOffloadPlayer since offload state enabled
michael@0 83 ChangeState(mPlayState);
michael@0 84 return;
michael@0 85 }
michael@0 86
michael@0 87 mAudioOffloadPlayer = nullptr;
michael@0 88 DECODER_LOG(PR_LOG_DEBUG, ("In %s Unable to start offload audio %d."
michael@0 89 "Switching to normal mode", __PRETTY_FUNCTION__, err));
michael@0 90 }
michael@0 91
michael@0 92 void MediaOmxDecoder::PauseStateMachine()
michael@0 93 {
michael@0 94 MOZ_ASSERT(NS_IsMainThread());
michael@0 95 GetReentrantMonitor().AssertCurrentThreadIn();
michael@0 96 DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
michael@0 97 if (!mDecoderStateMachine) {
michael@0 98 return;
michael@0 99 }
michael@0 100 StopProgress();
michael@0 101 mDecoderStateMachine->SetDormant(true);
michael@0 102 }
michael@0 103
michael@0 104 void MediaOmxDecoder::ResumeStateMachine()
michael@0 105 {
michael@0 106 MOZ_ASSERT(NS_IsMainThread());
michael@0 107 ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
michael@0 108 DECODER_LOG(PR_LOG_DEBUG, ("%s current time %f", __PRETTY_FUNCTION__,
michael@0 109 mCurrentTime));
michael@0 110
michael@0 111 if (!mDecoderStateMachine) {
michael@0 112 return;
michael@0 113 }
michael@0 114
michael@0 115 mFallbackToStateMachine = true;
michael@0 116 mAudioOffloadPlayer = nullptr;
michael@0 117 mRequestedSeekTarget = SeekTarget(mCurrentTime, SeekTarget::Accurate);
michael@0 118
michael@0 119 mNextState = mPlayState;
michael@0 120 ChangeState(PLAY_STATE_LOADING);
michael@0 121 mDecoderStateMachine->SetDormant(false);
michael@0 122 }
michael@0 123
michael@0 124 void MediaOmxDecoder::AudioOffloadTearDown()
michael@0 125 {
michael@0 126 MOZ_ASSERT(NS_IsMainThread());
michael@0 127 PlaybackPositionChanged();
michael@0 128 DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
michael@0 129 {
michael@0 130 // Audio offload player sent tear down event. Fallback to state machine
michael@0 131 ResumeStateMachine();
michael@0 132 }
michael@0 133 }
michael@0 134
michael@0 135 void MediaOmxDecoder::AddOutputStream(ProcessedMediaStream* aStream,
michael@0 136 bool aFinishWhenEnded)
michael@0 137 {
michael@0 138 MOZ_ASSERT(NS_IsMainThread());
michael@0 139 PlaybackPositionChanged();
michael@0 140
michael@0 141 if (mAudioOffloadPlayer) {
michael@0 142 // Offload player cannot handle MediaStream. Fallback
michael@0 143 ResumeStateMachine();
michael@0 144 }
michael@0 145
michael@0 146 MediaDecoder::AddOutputStream(aStream, aFinishWhenEnded);
michael@0 147 }
michael@0 148
michael@0 149 void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
michael@0 150 {
michael@0 151 MOZ_ASSERT(NS_IsMainThread());
michael@0 152 PlaybackPositionChanged();
michael@0 153
michael@0 154 if (mAudioOffloadPlayer &&
michael@0 155 ((aPlaybackRate != 0.0) || (aPlaybackRate != 1.0))) {
michael@0 156 // Offload player cannot handle playback rate other than 1/0. Fallback
michael@0 157 ResumeStateMachine();
michael@0 158 }
michael@0 159
michael@0 160 MediaDecoder::SetPlaybackRate(aPlaybackRate);
michael@0 161 }
michael@0 162
michael@0 163 void MediaOmxDecoder::ChangeState(PlayState aState)
michael@0 164 {
michael@0 165 MOZ_ASSERT(NS_IsMainThread());
michael@0 166 // Keep MediaDecoder state in sync with MediaElement irrespective of offload
michael@0 167 // playback so it will continue to work in normal mode when offloading fails
michael@0 168 // in between
michael@0 169 MediaDecoder::ChangeState(aState);
michael@0 170
michael@0 171 if (mAudioOffloadPlayer) {
michael@0 172 status_t err = mAudioOffloadPlayer->ChangeState(aState);
michael@0 173 if (err != OK) {
michael@0 174 ResumeStateMachine();
michael@0 175 }
michael@0 176 }
michael@0 177 }
michael@0 178
michael@0 179 void MediaOmxDecoder::ApplyStateToStateMachine(PlayState aState)
michael@0 180 {
michael@0 181 MOZ_ASSERT(NS_IsMainThread());
michael@0 182 // During offload playback, state machine should be in dormant state.
michael@0 183 // ApplyStateToStateMachine() can change state machine state to
michael@0 184 // something else or reset the seek time. So don't call this when audio is
michael@0 185 // offloaded
michael@0 186 if (!mAudioOffloadPlayer) {
michael@0 187 MediaDecoder::ApplyStateToStateMachine(aState);
michael@0 188 }
michael@0 189 }
michael@0 190
michael@0 191 void MediaOmxDecoder::PlaybackPositionChanged()
michael@0 192 {
michael@0 193 MOZ_ASSERT(NS_IsMainThread());
michael@0 194 if (!mAudioOffloadPlayer) {
michael@0 195 MediaDecoder::PlaybackPositionChanged();
michael@0 196 return;
michael@0 197 }
michael@0 198
michael@0 199 if (!mOwner || mShuttingDown) {
michael@0 200 return;
michael@0 201 }
michael@0 202
michael@0 203 double lastTime = mCurrentTime;
michael@0 204 {
michael@0 205 ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
michael@0 206 mCurrentTime = mAudioOffloadPlayer->GetMediaTimeSecs();
michael@0 207 }
michael@0 208 if (mOwner && lastTime != mCurrentTime) {
michael@0 209 FireTimeUpdate();
michael@0 210 }
michael@0 211 }
michael@0 212
michael@0 213 void MediaOmxDecoder::SetElementVisibility(bool aIsVisible)
michael@0 214 {
michael@0 215 MOZ_ASSERT(NS_IsMainThread());
michael@0 216 if (mAudioOffloadPlayer) {
michael@0 217 mAudioOffloadPlayer->SetElementVisibility(aIsVisible);
michael@0 218 }
michael@0 219 }
michael@0 220
michael@0 221 void MediaOmxDecoder::UpdateReadyStateForData()
michael@0 222 {
michael@0 223 MOZ_ASSERT(NS_IsMainThread());
michael@0 224 if (!mAudioOffloadPlayer) {
michael@0 225 MediaDecoder::UpdateReadyStateForData();
michael@0 226 return;
michael@0 227 }
michael@0 228
michael@0 229 if (!mOwner || mShuttingDown)
michael@0 230 return;
michael@0 231 mOwner->UpdateReadyStateForData(mAudioOffloadPlayer->GetNextFrameStatus());
michael@0 232 }
michael@0 233
michael@0 234 void MediaOmxDecoder::SetVolume(double aVolume)
michael@0 235 {
michael@0 236 MOZ_ASSERT(NS_IsMainThread());
michael@0 237 if (!mAudioOffloadPlayer) {
michael@0 238 MediaDecoder::SetVolume(aVolume);
michael@0 239 return;
michael@0 240 }
michael@0 241 mAudioOffloadPlayer->SetVolume(aVolume);
michael@0 242 }
michael@0 243
michael@0 244 } // namespace mozilla

mercurial