gecko-dev/dom/media/omx/AudioOutput.cpp
Wes Kocher 4e9f80ed2e Backed out 14 changesets (bug 1165515) for b2g mochitest-6 permafail CLOSED TREE
Backed out changeset 9b97e2aa2ed9 (bug 1165515)
Backed out changeset 150606c022a2 (bug 1165515)
Backed out changeset 4e875a488349 (bug 1165515)
Backed out changeset 467e7feeb546 (bug 1165515)
Backed out changeset d6b6cc373197 (bug 1165515)
Backed out changeset 0615265b593c (bug 1165515)
Backed out changeset fafd1dce9f08 (bug 1165515)
Backed out changeset d1df869245f9 (bug 1165515)
Backed out changeset 6876a7c63611 (bug 1165515)
Backed out changeset b7841c94a9a3 (bug 1165515)
Backed out changeset e5e3617f7c73 (bug 1165515)
Backed out changeset 39be3db95978 (bug 1165515)
Backed out changeset 0ec74176f8de (bug 1165515)
Backed out changeset 5b928dd10d71 (bug 1165515)
2015-06-01 17:57:58 -07:00

239 lines
5.9 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/*
* Copyright (c) 2014 The Linux Foundation. All rights reserved.
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stagefright/foundation/ADebug.h>
#include "AudioOutput.h"
#include "mozilla/Logging.h"
namespace mozilla {
extern PRLogModuleInfo* gAudioOffloadPlayerLog;
#define AUDIO_OFFLOAD_LOG(type, msg) \
MOZ_LOG(gAudioOffloadPlayerLog, type, msg)
using namespace android;
AudioOutput::AudioOutput(int aSessionId, int aUid) :
mCallbackCookie(nullptr),
mCallback(nullptr),
mCallbackData(nullptr),
mUid(aUid),
mSessionId(aSessionId)
{
if (!gAudioOffloadPlayerLog) {
gAudioOffloadPlayerLog = PR_NewLogModule("AudioOffloadPlayer");
}
}
AudioOutput::~AudioOutput()
{
Close();
}
ssize_t AudioOutput::FrameSize() const
{
if (!mTrack.get()) {
return NO_INIT;
}
return mTrack->frameSize();
}
status_t AudioOutput::GetPosition(uint32_t *aPosition) const
{
if (!mTrack.get()) {
return NO_INIT;
}
return mTrack->getPosition(aPosition);
}
status_t AudioOutput::SetVolume(float aVolume) const
{
if (!mTrack.get()) {
return NO_INIT;
}
return mTrack->setVolume(aVolume);
}
status_t AudioOutput::SetParameters(const String8& aKeyValuePairs)
{
if (!mTrack.get()) {
return NO_INIT;
}
return mTrack->setParameters(aKeyValuePairs);
}
status_t AudioOutput::Open(uint32_t aSampleRate,
int aChannelCount,
audio_channel_mask_t aChannelMask,
audio_format_t aFormat,
AudioCallback aCb,
void* aCookie,
audio_output_flags_t aFlags,
const audio_offload_info_t *aOffloadInfo)
{
mCallback = aCb;
mCallbackCookie = aCookie;
if (((aFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) || !aCb ||
!aOffloadInfo) {
return BAD_VALUE;
}
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("open(%u, %d, 0x%x, 0x%x, %d 0x%x)",
aSampleRate, aChannelCount, aChannelMask, aFormat, mSessionId, aFlags));
if (aChannelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
aChannelMask = audio_channel_out_mask_from_count(aChannelCount);
if (0 == aChannelMask) {
AUDIO_OFFLOAD_LOG(PR_LOG_ERROR, ("open() error, can\'t derive mask for"
" %d audio channels", aChannelCount));
return NO_INIT;
}
}
sp<AudioTrack> t;
CallbackData* newcbd = new CallbackData(this);
t = new AudioTrack(
AUDIO_STREAM_MUSIC,
aSampleRate,
aFormat,
aChannelMask,
0, // Offloaded tracks will get frame count from AudioFlinger
aFlags,
CallbackWrapper,
newcbd,
0, // notification frames
mSessionId,
AudioTrack::TRANSFER_CALLBACK,
aOffloadInfo,
mUid);
if ((!t.get()) || (t->initCheck() != NO_ERROR)) {
AUDIO_OFFLOAD_LOG(PR_LOG_ERROR, ("Unable to create audio track"));
delete newcbd;
return NO_INIT;
}
mCallbackData = newcbd;
t->setVolume(1.0);
mTrack = t;
return NO_ERROR;
}
status_t AudioOutput::Start()
{
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
if (!mTrack.get()) {
return NO_INIT;
}
mTrack->setVolume(1.0);
return mTrack->start();
}
void AudioOutput::Stop()
{
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
if (mTrack.get()) {
mTrack->stop();
}
}
void AudioOutput::Flush()
{
if (mTrack.get()) {
mTrack->flush();
}
}
void AudioOutput::Pause()
{
if (mTrack.get()) {
mTrack->pause();
}
}
void AudioOutput::Close()
{
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
mTrack.clear();
delete mCallbackData;
mCallbackData = nullptr;
}
// static
void AudioOutput::CallbackWrapper(int aEvent, void* aCookie, void* aInfo)
{
CallbackData* data = (CallbackData*) aCookie;
data->Lock();
AudioOutput* me = data->GetOutput();
AudioTrack::Buffer* buffer = (AudioTrack::Buffer*) aInfo;
if (!me) {
// no output set, likely because the track was scheduled to be reused
// by another player, but the format turned out to be incompatible.
data->Unlock();
if (buffer) {
buffer->size = 0;
}
return;
}
switch(aEvent) {
case AudioTrack::EVENT_MORE_DATA: {
size_t actualSize = (*me->mCallback)(me, buffer->raw, buffer->size,
me->mCallbackCookie, CB_EVENT_FILL_BUFFER);
if (actualSize == 0 && buffer->size > 0) {
// We've reached EOS but the audio track is not stopped yet,
// keep playing silence.
memset(buffer->raw, 0, buffer->size);
actualSize = buffer->size;
}
buffer->size = actualSize;
} break;
case AudioTrack::EVENT_STREAM_END:
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Callback wrapper: EVENT_STREAM_END"));
(*me->mCallback)(me, nullptr /* buffer */, 0 /* size */,
me->mCallbackCookie, CB_EVENT_STREAM_END);
break;
case AudioTrack::EVENT_NEW_IAUDIOTRACK :
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Callback wrapper: EVENT_TEAR_DOWN"));
(*me->mCallback)(me, nullptr /* buffer */, 0 /* size */,
me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
break;
default:
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("received unknown event type: %d in"
" Callback wrapper!", aEvent));
break;
}
data->Unlock();
}
} // namespace mozilla