summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice/MediaPlayerService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmediaplayerservice/MediaPlayerService.cpp')
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp152
1 files changed, 130 insertions, 22 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9bedff1..414c262 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1,5 +1,9 @@
/*
**
+** Copyright (c) 2012, The Linux Foundation. All rights reserved.
+** Not a Contribution, Apache license notifications and license are retained
+** for attribution purposes only.
+**
** Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -74,6 +78,7 @@
#include "Crypto.h"
#include "HDCP.h"
#include "RemoteDisplay.h"
+#define DEFAULT_SAMPLE_RATE 44100
namespace {
using android::media::Metadata;
@@ -1363,6 +1368,22 @@ status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const
return mTrack->getPosition(position);
}
+#ifdef QCOM_HARDWARE
+ssize_t MediaPlayerService::AudioOutput::sampleRate() const
+{
+ if (mTrack == 0) return NO_INIT;
+ return DEFAULT_SAMPLE_RATE;
+}
+
+status_t MediaPlayerService::AudioOutput::getTimeStamp(uint64_t *tstamp)
+{
+ if (tstamp == 0) return BAD_VALUE;
+ if (mTrack == 0) return NO_INIT;
+ mTrack->getTimeStamp(tstamp);
+ return NO_ERROR;
+}
+#endif
+
status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const
{
if (mTrack == 0) return NO_INIT;
@@ -1379,6 +1400,65 @@ status_t MediaPlayerService::AudioOutput::open(
mCallback = cb;
mCallbackCookie = cookie;
+#ifdef QCOM_HARDWARE
+ if (flags & AUDIO_OUTPUT_FLAG_LPA || flags & AUDIO_OUTPUT_FLAG_TUNNEL) {
+ ALOGV("AudioOutput open: with flags %x",flags);
+ channelMask = audio_channel_out_mask_from_count(channelCount);
+ if (0 == channelMask) {
+ ALOGE("open() error, can't derive mask for %d audio channels", channelCount);
+ return NO_INIT;
+ }
+ AudioTrack *audioTrack = NULL;
+ CallbackData *newcbd = NULL;
+ if (mCallback != NULL) {
+ newcbd = new CallbackData(this);
+ audioTrack = new AudioTrack(
+ mStreamType,
+ sampleRate,
+ format,
+ channelMask,
+ 0,
+ flags,
+ CallbackWrapper,
+ newcbd,
+ 0,
+ mSessionId);
+ if ((audioTrack == 0) || (audioTrack->initCheck() != NO_ERROR)) {
+ ALOGE("Unable to create audio track");
+ delete audioTrack;
+ delete newcbd;
+ return NO_INIT;
+ }
+ } else {
+ ALOGE("no callback supplied");
+ return NO_INIT;
+ }
+
+ if (mRecycledTrack) {
+ //usleep(500000);
+ // if we're not going to reuse the track, unblock and flush it
+ if (mCallbackData != NULL) {
+ mCallbackData->setOutput(NULL);
+ mCallbackData->endTrackSwitch();
+ }
+ mRecycledTrack->flush();
+ delete mRecycledTrack;
+ mRecycledTrack = NULL;
+ delete mCallbackData;
+ mCallbackData = NULL;
+ close();
+ }
+
+ ALOGV("setVolume");
+ mCallbackData = newcbd;
+ audioTrack->setVolume(mLeftVolume, mRightVolume);
+ mSampleRateHz = sampleRate;
+ mFlags = flags;
+ mTrack = audioTrack;
+ return NO_ERROR;
+ }
+#endif
+
// Check argument "bufferCount" against the mininum buffer count
if (bufferCount < mMinBufferCount) {
ALOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount);
@@ -1551,7 +1631,7 @@ void MediaPlayerService::AudioOutput::switchToNextOutput() {
ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
{
- LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
+ //LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
//ALOGV("write(%p, %u)", buffer, size);
if (mTrack) {
@@ -1637,35 +1717,56 @@ status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
void MediaPlayerService::AudioOutput::CallbackWrapper(
int event, void *cookie, void *info) {
//ALOGV("callbackwrapper");
- if (event != AudioTrack::EVENT_MORE_DATA) {
- return;
- }
-
- CallbackData *data = (CallbackData*)cookie;
- data->lock();
- AudioOutput *me = data->getOutput();
- AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
- if (me == NULL) {
- // no output set, likely because the track was scheduled to be reused
- // by another player, but the format turned out to be incompatible.
+#ifdef QCOM_HARDWARE
+ if (event == AudioTrack::EVENT_UNDERRUN) {
+ ALOGW("Event underrun");
+ CallbackData *data = (CallbackData*)cookie;
+ data->lock();
+ AudioOutput *me = data->getOutput();
+ if (me == NULL) {
+ // 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();
+ return;
+ }
+ ALOGD("Callback!!!");
+ (*me->mCallback)(
+ me, NULL, (size_t)AudioTrack::EVENT_UNDERRUN, me->mCallbackCookie);
data->unlock();
- buffer->size = 0;
return;
}
+#endif
+ if (event == AudioTrack::EVENT_MORE_DATA) {
+ CallbackData *data = (CallbackData*)cookie;
+ data->lock();
+ AudioOutput *me = data->getOutput();
+ AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
+ if (me == NULL) {
+ // 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();
+ buffer->size = 0;
+ return;
+ }
+
+ size_t actualSize = (*me->mCallback)(
+ me, buffer->raw, buffer->size, me->mCallbackCookie);
- size_t actualSize = (*me->mCallback)(
- me, buffer->raw, buffer->size, me->mCallbackCookie);
+ if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) {
+ // We've reached EOS but the audio track is not stopped yet,
+ // keep playing silence.
- if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) {
- // We've reached EOS but the audio track is not stopped yet,
- // keep playing silence.
+ memset(buffer->raw, 0, buffer->size);
+ actualSize = buffer->size;
+ }
- memset(buffer->raw, 0, buffer->size);
- actualSize = buffer->size;
+ buffer->size = actualSize;
+ data->unlock();
}
- buffer->size = actualSize;
- data->unlock();
+ return;
+
+
}
int MediaPlayerService::AudioOutput::getSessionId() const
@@ -1700,6 +1801,13 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const
return NO_ERROR;
}
+#ifdef QCOM_HARDWARE
+ssize_t MediaPlayerService::AudioCache::sampleRate() const
+{
+ return mSampleRate;
+}
+#endif
+
status_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const
{
if (written == 0) return BAD_VALUE;