summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Fitzgerald <rf@opensource.wolfsonmicro.com>2013-03-25 16:54:37 +0000
committerEric Laurent <elaurent@google.com>2013-06-27 17:16:24 -0700
commitad3af3305f024bcbbd55c894a4995e449498e1ba (patch)
tree2e242d4c49cce9faefc28665c6ee63a2a5da170c
parent7919fa2c33b1fa7f5e49b2188d671bfe519c231e (diff)
downloadframeworks_av-ad3af3305f024bcbbd55c894a4995e449498e1ba.zip
frameworks_av-ad3af3305f024bcbbd55c894a4995e449498e1ba.tar.gz
frameworks_av-ad3af3305f024bcbbd55c894a4995e449498e1ba.tar.bz2
Public API changes for audio offload support.
NOTE: this does _not_ include all private member variables added to classes as part of offload support. Only public/protected functions and stubs functions/variables needed to make the changes buildable. - isOffloadSupported() added to audio policy service A stub implementation is required to build, this always returns false - setParameters() added to IAudioTrack A stub implementation is required to build, this always returns INVALID_OPERATION - CBlk flag for stream end - Change AudioSystem::getRenderPosition() to take an audio_output_t so caller can specify which output to query - Add AudioSystem::isOffloadSupported() This is fully implemented down to the AudioFlinger function AudioPolicyServer::isOffloadSupported() which is just a stub that always returns false. - Add EVENT_STREAM_END to AudioTrack interface. STREAM_END is used to signal when the hardware has actually finished playing all the data it was sent. - Add event type enumeration to media player interface AudioSink callbacks so that the same callback can be used to handle multiple types of event. For offloaded tracks we also have to handle STREAM_END and TEAR_DOWN events - Pass audio_offload_info_t to various functions used for opening outputs, tracks and audio players. This passes additional information about the compressed stream down to the HAL when using offload. For publicly-available APIs this is an optional parameter (for some of the internal and low-level APIs around the HAL interface it is mandatory) - Add getParameters() and setParameters() API to AudioTrack Currently dummy implementations. - Change AudioPlayer contructor so that it takes a set of bitflags defining what options are required. This replaces the original bool which only specified whether to use deep buffering. - Changes to StageFright class definition related to handling tearing-down of an offloaded track when we need to switch back to software decode - Define new StageFright utility functions used for offloaded tracks Currently dummy implementations. - AudioFlinger changes to use extended audio_config_t. Fills in audio_offload_info_t member if this info is passed in when opening an output. - libvideoeditor changes required to add the new event type parameter to AudioSink callback functions - libmediaplayerservice changes required to add the new event type parameter to AudioSink callback functions Change-Id: I3ab41138aa1083d81fe83b886a9b1021ec7320f1 Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com> Signed-off-by: Eric Laurent <elaurent@google.com>
-rw-r--r--include/media/AudioSystem.h13
-rw-r--r--include/media/AudioTrack.h34
-rw-r--r--include/media/IAudioFlinger.h4
-rw-r--r--include/media/IAudioPolicyService.h6
-rw-r--r--include/media/IAudioTrack.h4
-rw-r--r--include/media/MediaPlayerInterface.h17
-rw-r--r--include/media/stagefright/AudioPlayer.h13
-rw-r--r--include/media/stagefright/Utils.h11
-rw-r--r--include/private/media/AudioTrackShared.h4
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorAudioPlayer.cpp9
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorAudioPlayer.h3
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.cpp6
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.h3
-rw-r--r--media/libmedia/AudioSystem.cpp23
-rw-r--r--media/libmedia/AudioTrack.cpp31
-rw-r--r--media/libmedia/IAudioFlinger.cpp3
-rw-r--r--media/libmedia/IAudioPolicyService.cpp12
-rw-r--r--media/libmedia/IAudioTrack.cpp18
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp12
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h6
-rw-r--r--media/libstagefright/AudioPlayer.cpp7
-rw-r--r--media/libstagefright/Utils.cpp19
-rw-r--r--media/libstagefright/include/AwesomePlayer.h17
-rw-r--r--media/libstagefright/include/ESDS.h6
-rw-r--r--services/audioflinger/AudioFlinger.cpp37
-rw-r--r--services/audioflinger/AudioFlinger.h5
-rw-r--r--services/audioflinger/AudioPolicyService.cpp15
-rw-r--r--services/audioflinger/AudioPolicyService.h4
-rw-r--r--services/audioflinger/Tracks.cpp4
29 files changed, 281 insertions, 65 deletions
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index b11c812..09160cc 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -128,8 +128,10 @@ public:
// - BAD_VALUE: invalid parameter
// NOTE: this feature is not supported on all hardware platforms and it is
// necessary to check returned status before using the returned values.
- static status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
- audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
+ static status_t getRenderPosition(audio_io_handle_t output,
+ size_t *halFrames,
+ size_t *dspFrames,
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
// return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
static size_t getInputFramesLost(audio_io_handle_t ioHandle);
@@ -197,7 +199,8 @@ public:
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE);
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL);
static status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session = 0);
@@ -245,6 +248,10 @@ public:
static uint32_t getPrimaryOutputSamplingRate();
static size_t getPrimaryOutputFrameCount();
+ // Check if hw offload is possible for given format, stream type, sample rate,
+ // bit rate, duration, video and streaming or offload property is enabled
+ static bool isOffloadSupported(const audio_offload_info_t& info);
+
// ----------------------------------------------------------------------------
private:
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index e9bb76a..6727601 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -60,6 +60,8 @@ public:
// Not currently used by android.media.AudioTrack.
EVENT_NEW_IAUDIOTRACK = 6, // IAudioTrack was re-created, either due to re-routing and
// voluntary invalidation by mediaserver, or mediaserver crash.
+ EVENT_STREAM_END = 7, // Sent after all the buffers queued in AF and HW are played
+ // back (after stop is called)
};
/* Client should declare Buffer on the stack and pass address to obtainBuffer()
@@ -175,7 +177,8 @@ public:
void* user = NULL,
int notificationFrames = 0,
int sessionId = 0,
- transfer_type transferType = TRANSFER_DEFAULT);
+ transfer_type transferType = TRANSFER_DEFAULT,
+ const audio_offload_info_t *offloadInfo = NULL);
/* Creates an audio track and registers it with AudioFlinger.
* With this constructor, the track is configured for static buffer mode.
@@ -198,7 +201,8 @@ public:
void* user = NULL,
int notificationFrames = 0,
int sessionId = 0,
- transfer_type transferType = TRANSFER_DEFAULT);
+ transfer_type transferType = TRANSFER_DEFAULT,
+ const audio_offload_info_t *offloadInfo = NULL);
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
* Also destroys all resources associated with the AudioTrack.
@@ -233,7 +237,8 @@ public:
const sp<IMemory>& sharedBuffer = 0,
bool threadCanCallJava = false,
int sessionId = 0,
- transfer_type transferType = TRANSFER_DEFAULT);
+ transfer_type transferType = TRANSFER_DEFAULT,
+ const audio_offload_info_t *offloadInfo = NULL);
/* Result of constructing the AudioTrack. This must be checked
* before using any AudioTrack API (except for set()), because using
@@ -521,6 +526,15 @@ private:
struct timespec *elapsed = NULL, size_t *nonContig = NULL);
public:
+//EL_FIXME to be reconciled with new obtainBuffer() return codes and control block proxy
+// enum {
+// NO_MORE_BUFFERS = 0x80000001, // same name in AudioFlinger.h, ok to be different value
+// TEAR_DOWN = 0x80000002,
+// STOPPED = 1,
+// STREAM_END_WAIT,
+// STREAM_END
+// };
+
/* Release a filled buffer of "audioBuffer->frameCount" frames for AudioFlinger to process. */
// FIXME make private when obtainBuffer() for TRANSFER_OBTAIN is removed
void releaseBuffer(Buffer* audioBuffer);
@@ -550,6 +564,15 @@ public:
*/
uint32_t getUnderrunFrames() const;
+ /* Get the flags */
+ audio_output_flags_t getFlags() const { return mFlags; }
+
+ /* Set parameters - only possible when using direct output */
+ status_t setParameters(const String8& keyValuePairs);
+
+ /* Get parameters */
+ String8 getParameters(const String8& keys);
+
protected:
/* copying audio tracks is not allowed */
AudioTrack(const AudioTrack& other);
@@ -590,8 +613,11 @@ protected:
// NS_NEVER never again
static const nsecs_t NS_WHENEVER = -1, NS_INACTIVE = -2, NS_NEVER = -3;
nsecs_t processAudioBuffer(const sp<AudioTrackThread>& thread);
+ status_t processStreamEnd(int32_t waitCount);
+
// caller must hold lock on mLock for all _l methods
+
status_t createTrack_l(audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
@@ -607,6 +633,8 @@ protected:
void setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount);
audio_io_handle_t getOutput_l();
+ status_t getPosition_l(uint32_t *position);
+
// FIXME enum is faster than strcmp() for parameter 'from'
status_t restoreTrack_l(const char *from);
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 9c3067e..f8a9f2b 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -49,6 +49,7 @@ public:
TRACK_DEFAULT = 0, // client requests a default AudioTrack
TRACK_TIMED = 1, // client requests a TimedAudioTrack
TRACK_FAST = 2, // client requests a fast AudioTrack or AudioRecord
+ TRACK_OFFLOAD = 4, // client requests offload to hw codec
};
typedef uint32_t track_flags_t;
@@ -137,7 +138,8 @@ public:
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
- audio_output_flags_t flags) = 0;
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo = NULL) = 0;
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2) = 0;
virtual status_t closeOutput(audio_io_handle_t output) = 0;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index b5ad4ef..09b9ea6 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -53,7 +53,8 @@ public:
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
audio_channel_mask_t channelMask = 0,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE) = 0;
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL) = 0;
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session = 0) = 0;
@@ -95,6 +96,9 @@ public:
virtual status_t queryDefaultPreProcessing(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count) = 0;
+ // Check if offload is possible for given format, stream type, sample rate,
+ // bit rate, duration, video and streaming or offload property is enabled
+ virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0;
};
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index 144be0e..1014403 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -25,6 +25,7 @@
#include <binder/IInterface.h>
#include <binder/IMemory.h>
#include <utils/LinearTransform.h>
+#include <utils/String8.h>
namespace android {
@@ -82,6 +83,9 @@ public:
or Tungsten time. The values for target are defined in AudioTrack.h */
virtual status_t setMediaTimeTransform(const LinearTransform& xform,
int target) = 0;
+
+ /* Send parameters to the audio hardware */
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 9a75f81..61f7dc7 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -74,9 +74,18 @@ public:
// AudioSink: abstraction layer for audio output
class AudioSink : public RefBase {
public:
+ enum cb_event_t {
+ CB_EVENT_FILL_BUFFER, // Request to write more data to buffer.
+ CB_EVENT_STREAM_END, // Sent after all the buffers queued in AF and HW are played
+ // back (after stop is called)
+ CB_EVENT_TEAR_DOWN // The AudioTrack was invalidated due to use case change:
+ // Need to re-evaluate offloading options
+ };
+
// Callback returns the number of bytes actually written to the buffer.
typedef size_t (*AudioCallback)(
- AudioSink *audioSink, void *buffer, size_t size, void *cookie);
+ AudioSink *audioSink, void *buffer, size_t size, void *cookie,
+ cb_event_t event);
virtual ~AudioSink() {}
virtual bool ready() const = 0; // audio output is open and ready
@@ -99,7 +108,8 @@ public:
int bufferCount=DEFAULT_AUDIOSINK_BUFFERCOUNT,
AudioCallback cb = NULL,
void *cookie = NULL,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE) = 0;
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL) = 0;
virtual void start() = 0;
virtual ssize_t write(const void* buffer, size_t size) = 0;
@@ -110,6 +120,9 @@ public:
virtual status_t setPlaybackRatePermille(int32_t rate) { return INVALID_OPERATION; }
virtual bool needsTrailingPadding() { return true; }
+
+ virtual status_t setParameters(const String8& keyValuePairs) { return NO_ERROR; };
+ virtual String8 getParameters(const String8& keys) { return String8::empty(); };
};
MediaPlayerBase() : mCookie(0), mNotify(0) {}
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 3bf046d..ec9f2df 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -36,8 +36,13 @@ public:
SEEK_COMPLETE
};
+ enum {
+ ALLOW_DEEP_BUFFERING = 0x01,
+ USE_OFFLOAD = 0x02
+ };
+
AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink,
- bool allowDeepBuffering = false,
+ uint32_t flags = 0,
AwesomePlayer *audioObserver = NULL);
virtual ~AudioPlayer();
@@ -67,6 +72,8 @@ public:
status_t setPlaybackRatePermille(int32_t ratePermille);
+ void notifyAudioEOS();
+
private:
friend class VideoEditorAudioPlayer;
sp<MediaSource> mSource;
@@ -107,7 +114,8 @@ private:
static size_t AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
- void *data, size_t size, void *me);
+ void *data, size_t size, void *me,
+ MediaPlayerBase::AudioSink::cb_event_t event);
size_t fillBuffer(void *data, size_t size);
@@ -116,6 +124,7 @@ private:
void reset();
uint32_t getNumFramesPendingPlayout() const;
+ int64_t getOutputPlayPositionUs_l() const;
AudioPlayer(const AudioPlayer &);
AudioPlayer &operator=(const AudioPlayer &);
diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h
index 73940d3..c24f612 100644
--- a/include/media/stagefright/Utils.h
+++ b/include/media/stagefright/Utils.h
@@ -22,6 +22,8 @@
#include <stdint.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
+#include <system/audio.h>
+#include <media/MediaPlayerInterface.h>
namespace android {
@@ -48,6 +50,15 @@ void convertMessageToMetaData(
AString MakeUserAgent();
+// Convert a MIME type to a AudioSystem::audio_format
+status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime);
+
+// Send information from MetaData to the HAL via AudioSink
+status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta);
+
+// Check whether the stream defined by meta can be offloaded to hardware
+bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming);
+
} // namespace android
#endif // UTILS_H_
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index ef5bb8d..b41684a 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -44,6 +44,10 @@ namespace android {
#define CBLK_BUFFER_END 0x80 // set by server when the position reaches end of buffer if not looping
#define CBLK_OVERRUN 0x100 // set by server immediately on input overrun, cleared by client
#define CBLK_INTERRUPT 0x200 // set by client on interrupt(), cleared by client in obtainBuffer()
+#define CBLK_STREAM_END_DONE 0x400 // set by server on render completion, cleared by client
+
+//EL_FIXME 20 seconds may not be enough and must be reconciled with new obtainBuffer implementation
+#define MAX_RUN_OFFLOADED_TIMEOUT_MS 20000 //assuming upto a maximum of 20 seconds of offloaded
struct AudioTrackSharedStreaming {
// similar to NBAIO MonoPipe
diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
index 3fa8b87..dc360a5 100755
--- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
@@ -575,10 +575,15 @@ void VideoEditorAudioPlayer::reset() {
size_t VideoEditorAudioPlayer::AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
- void *buffer, size_t size, void *cookie) {
+ void *buffer, size_t size, void *cookie,
+ MediaPlayerBase::AudioSink::cb_event_t event) {
VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie;
- return me->fillBuffer(buffer, size);
+ if (event == MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER ) {
+ return me->fillBuffer(buffer, size);
+ } else {
+ return 0;
+ }
}
diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.h b/libvideoeditor/lvpp/VideoEditorAudioPlayer.h
index a5616c1..d2e652d 100755
--- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.h
+++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.h
@@ -124,7 +124,8 @@ private:
size_t fillBuffer(void *data, size_t size);
static size_t AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
- void *data, size_t size, void *me);
+ void *data, size_t size, void *me,
+ MediaPlayerBase::AudioSink::cb_event_t event);
void reset();
void clear();
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index 4a14b40..3384e34 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -391,7 +391,8 @@ status_t VideoEditorPlayer::VeAudioOutput::getFramesWritten(uint32_t *written) c
status_t VideoEditorPlayer::VeAudioOutput::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie, audio_output_flags_t flags) {
+ AudioCallback cb, void *cookie, audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo) {
mCallback = cb;
mCallbackCookie = cookie;
@@ -545,7 +546,8 @@ void VideoEditorPlayer::VeAudioOutput::CallbackWrapper(
AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
size_t actualSize = (*me->mCallback)(
- me, buffer->raw, buffer->size, me->mCallbackCookie);
+ me, buffer->raw, buffer->size, me->mCallbackCookie,
+ MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER);
buffer->size = actualSize;
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h
index defc90d..69323c3 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.h
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.h
@@ -52,7 +52,8 @@ class VideoEditorPlayer : public MediaPlayerInterface {
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie, audio_output_flags_t flags);
+ AudioCallback cb, void *cookie, audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo);
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 693df60..a6dedec 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -361,8 +361,8 @@ status_t AudioSystem::setVoiceVolume(float value)
return af->setVoiceVolume(value);
}
-status_t AudioSystem::getRenderPosition(size_t *halFrames, size_t *dspFrames,
- audio_stream_type_t stream)
+status_t AudioSystem::getRenderPosition(audio_io_handle_t output, size_t *halFrames,
+ size_t *dspFrames, audio_stream_type_t stream)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
@@ -371,7 +371,11 @@ status_t AudioSystem::getRenderPosition(size_t *halFrames, size_t *dspFrames,
stream = AUDIO_STREAM_MUSIC;
}
- return af->getRenderPosition(halFrames, dspFrames, getOutput(stream));
+ if (output == 0) {
+ output = getOutput(stream);
+ }
+
+ return af->getRenderPosition(halFrames, dspFrames, output);
}
size_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
@@ -585,11 +589,12 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
- return aps->getOutput(stream, samplingRate, format, channelMask, flags);
+ return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
}
status_t AudioSystem::startOutput(audio_io_handle_t output,
@@ -771,6 +776,14 @@ void AudioSystem::clearAudioConfigCache()
gOutputs.clear();
}
+bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info)
+{
+ ALOGV("isOffloadSupported()");
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return false;
+ return aps->isOffloadSupported(info);
+}
+
// ---------------------------------------------------------------------------
void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who) {
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index faca054..2af162c 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -97,7 +97,8 @@ AudioTrack::AudioTrack(
void* user,
int notificationFrames,
int sessionId,
- transfer_type transferType)
+ transfer_type transferType,
+ const audio_offload_info_t *offloadInfo)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -105,7 +106,7 @@ AudioTrack::AudioTrack(
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType);
+ 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo);
}
AudioTrack::AudioTrack(
@@ -119,7 +120,8 @@ AudioTrack::AudioTrack(
void* user,
int notificationFrames,
int sessionId,
- transfer_type transferType)
+ transfer_type transferType,
+ const audio_offload_info_t *offloadInfo)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -127,7 +129,7 @@ AudioTrack::AudioTrack(
{
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
- sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType);
+ sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo);
}
AudioTrack::~AudioTrack()
@@ -164,7 +166,8 @@ status_t AudioTrack::set(
const sp<IMemory>& sharedBuffer,
bool threadCanCallJava,
int sessionId,
- transfer_type transferType)
+ transfer_type transferType,
+ const audio_offload_info_t *offloadInfo)
{
switch (transferType) {
case TRANSFER_DEFAULT:
@@ -284,7 +287,8 @@ status_t AudioTrack::set(
audio_io_handle_t output = AudioSystem::getOutput(
streamType,
sampleRate, format, channelMask,
- flags);
+ flags,
+ offloadInfo);
if (output == 0) {
ALOGE("Could not get audio output for stream type %d", streamType);
@@ -1543,6 +1547,21 @@ status_t AudioTrack::restoreTrack_l(const char *from)
return result;
}
+status_t AudioTrack::setParameters(const String8& keyValuePairs)
+{
+ AutoMutex lock(mLock);
+ if (mAudioTrack != 0) {
+ return mAudioTrack->setParameters(keyValuePairs);
+ } else {
+ return NO_INIT;
+ }
+}
+
+String8 AudioTrack::getParameters(const String8& keys)
+{
+ return String8::empty();
+}
+
status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
{
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 2f18680..e4df77d 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -361,7 +361,8 @@ public:
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
Parcel data, reply;
audio_devices_t devices = pDevices ? *pDevices : (audio_devices_t)0;
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 386c351..57de58f 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -56,7 +56,8 @@ enum {
GET_DEVICES_FOR_STREAM,
QUERY_DEFAULT_PRE_PROCESSING,
SET_EFFECT_ENABLED,
- IS_STREAM_ACTIVE_REMOTELY
+ IS_STREAM_ACTIVE_REMOTELY,
+ IS_OFFLOAD_SUPPORTED
};
class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
@@ -126,7 +127,8 @@ public:
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -374,6 +376,12 @@ public:
*count = retCount;
return status;
}
+
+ virtual bool isOffloadSupported(const audio_offload_info_t& info)
+ {
+ // stub function
+ return false;
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index e92f8aa..a2b49a3 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -39,6 +39,7 @@ enum {
ALLOCATE_TIMED_BUFFER,
QUEUE_TIMED_BUFFER,
SET_MEDIA_TIME_TRANSFORM,
+ SET_PARAMETERS
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -154,6 +155,17 @@ public:
}
return status;
}
+
+ virtual status_t setParameters(const String8& keyValuePairs) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeString8(keyValuePairs);
+ status_t status = remote()->transact(SET_PARAMETERS, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -223,6 +235,12 @@ status_t BnAudioTrack::onTransact(
reply->writeInt32(setMediaTimeTransform(xform, target));
return NO_ERROR;
} break;
+ case SET_PARAMETERS: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ String8 keyValuePairs(data.readString8());
+ reply->writeInt32(setParameters(keyValuePairs));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index fa1ff36..53dce65 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1385,7 +1385,8 @@ status_t MediaPlayerService::AudioOutput::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
AudioCallback cb, void *cookie,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
mCallback = cb;
mCallbackCookie = cookie;
@@ -1661,7 +1662,8 @@ void MediaPlayerService::AudioOutput::CallbackWrapper(
}
size_t actualSize = (*me->mCallback)(
- me, buffer->raw, buffer->size, me->mCallbackCookie);
+ me, buffer->raw, buffer->size, me->mCallbackCookie,
+ CB_EVENT_FILL_BUFFER);
if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) {
// We've reached EOS but the audio track is not stopped yet,
@@ -1767,7 +1769,8 @@ bool CallbackThread::threadLoop() {
}
size_t actualSize =
- (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie);
+ (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie,
+ MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER);
if (actualSize > 0) {
sink->write(mBuffer, actualSize);
@@ -1781,7 +1784,8 @@ bool CallbackThread::threadLoop() {
status_t MediaPlayerService::AudioCache::open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
- AudioCallback cb, void *cookie, audio_output_flags_t flags)
+ AudioCallback cb, void *cookie, audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
ALOGV("open(%u, %d, 0x%x, %d, %d)", sampleRate, channelCount, channelMask, format, bufferCount);
if (mHeap->getHeapID() < 0) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index e586156..1f8bcc7 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -94,7 +94,8 @@ class MediaPlayerService : public BnMediaPlayerService
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount,
AudioCallback cb, void *cookie,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE);
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL);
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
@@ -195,7 +196,8 @@ class MediaPlayerService : public BnMediaPlayerService
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
audio_format_t format, int bufferCount = 1,
AudioCallback cb = NULL, void *cookie = NULL,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE);
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL);
virtual void start();
virtual ssize_t write(const void* buffer, size_t size);
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 92efae8..61d6746 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -34,7 +34,7 @@ namespace android {
AudioPlayer::AudioPlayer(
const sp<MediaPlayerBase::AudioSink> &audioSink,
- bool allowDeepBuffering,
+ uint32_t flags,
AwesomePlayer *observer)
: mInputBuffer(NULL),
mSampleRate(0),
@@ -52,7 +52,7 @@ AudioPlayer::AudioPlayer(
mFirstBufferResult(OK),
mFirstBuffer(NULL),
mAudioSink(audioSink),
- mAllowDeepBuffering(allowDeepBuffering),
+ mAllowDeepBuffering((flags & ALLOW_DEEP_BUFFERING) != 0),
mObserver(observer),
mPinnedTimeUs(-1ll) {
}
@@ -304,7 +304,8 @@ status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
// static
size_t AudioPlayer::AudioSinkCallback(
MediaPlayerBase::AudioSink *audioSink,
- void *buffer, size_t size, void *cookie) {
+ void *buffer, size_t size, void *cookie,
+ MediaPlayerBase::AudioSink::cb_event_t event) {
AudioPlayer *me = (AudioPlayer *)cookie;
return me->fillBuffer(buffer, size);
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index b0df379..e9789d3 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -471,5 +471,24 @@ AString MakeUserAgent() {
return ua;
}
+status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
+ const sp<MetaData>& meta)
+{
+ // stub
+ return OK;
+}
+
+status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime)
+{
+ // stub
+ return BAD_VALUE;
+}
+
+bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming)
+{
+ // stub
+ return false;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 2306f31..0d17d65 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -25,6 +25,7 @@
#include <media/stagefright/DataSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/TimeSource.h>
+#include <media/stagefright/MetaData.h>
#include <utils/threads.h>
#include <drm/DrmManagerClient.h>
@@ -100,7 +101,7 @@ struct AwesomePlayer {
void postAudioEOS(int64_t delayUs = 0ll);
void postAudioSeekComplete();
-
+ void postAudioTearDown();
status_t dump(int fd, const Vector<String16> &args) const;
private:
@@ -171,6 +172,7 @@ private:
ssize_t mActiveAudioTrackIndex;
sp<MediaSource> mAudioTrack;
+ sp<MediaSource> mOmxSource;
sp<MediaSource> mAudioSource;
AudioPlayer *mAudioPlayer;
int64_t mDurationUs;
@@ -211,7 +213,8 @@ private:
bool mAudioStatusEventPending;
sp<TimedEventQueue::Event> mVideoLagEvent;
bool mVideoLagEventPending;
-
+ sp<TimedEventQueue::Event> mAudioTearDownEvent;
+ bool mAudioTearDownEventPending;
sp<TimedEventQueue::Event> mAsyncPrepareEvent;
Condition mPreparedCondition;
bool mIsAsyncPrepare;
@@ -223,6 +226,8 @@ private:
void postStreamDoneEvent_l(status_t status);
void postCheckAudioStatusEvent(int64_t delayUs);
void postVideoLagEvent_l();
+ void postAudioTearDownEvent();
+
status_t play_l();
MediaBuffer *mVideoBuffer;
@@ -257,6 +262,7 @@ private:
void setAudioSource(sp<MediaSource> source);
status_t initAudioDecoder();
+
void setVideoSource(sp<MediaSource> source);
status_t initVideoDecoder(uint32_t flags = 0);
@@ -273,6 +279,9 @@ private:
void abortPrepare(status_t err);
void finishAsyncPrepare_l();
void onVideoLagUpdate();
+ void onAudioTearDownEvent();
+
+ void beginPrepareAsync_l();
bool getCachedDuration_l(int64_t *durationUs, bool *eos);
@@ -285,6 +294,7 @@ private:
void finishSeekIfNecessary(int64_t videoTimeUs);
void ensureCacheIsFetching_l();
+ void createAudioPlayer_l();
status_t startAudioPlayer_l(bool sendErrorNotification = true);
void shutdownVideoDecoder_l();
@@ -327,6 +337,9 @@ private:
Vector<TrackStat> mTracks;
} mStats;
+ bool mOffloadAudio;
+ bool mAudioTearDown;
+
status_t setVideoScalingMode(int32_t mode);
status_t setVideoScalingMode_l(int32_t mode);
status_t getTrackInfo(Parcel* reply) const;
diff --git a/media/libstagefright/include/ESDS.h b/media/libstagefright/include/ESDS.h
index 3a79951..2f40dae 100644
--- a/media/libstagefright/include/ESDS.h
+++ b/media/libstagefright/include/ESDS.h
@@ -33,6 +33,9 @@ public:
status_t getObjectTypeIndication(uint8_t *objectTypeIndication) const;
status_t getCodecSpecificInfo(const void **data, size_t *size) const;
+ status_t getCodecSpecificOffset(size_t *offset, size_t *size) const;
+ status_t getBitRate(uint32_t *brateMax, uint32_t *brateAvg) const;
+ status_t getStreamType(uint8_t *streamType) const;
private:
enum {
@@ -49,6 +52,9 @@ private:
size_t mDecoderSpecificOffset;
size_t mDecoderSpecificLength;
uint8_t mObjectTypeIndication;
+ uint8_t mStreamType;
+ uint32_t mBitRateMax;
+ uint32_t mBitRateAvg;
status_t skipDescriptorHeader(
size_t offset, size_t size,
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a6edb77..c8e8aba 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -981,11 +981,12 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
- struct audio_config config = {
- sample_rate: sampleRate,
- channel_mask: channelMask,
- format: format,
- };
+ struct audio_config config;
+ memset(&config, 0, sizeof(config));
+ config.sample_rate = sampleRate;
+ config.channel_mask = channelMask;
+ config.format = format;
+
audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
size_t size = dev->get_input_buffer_size(dev, &config);
mHardwareStatus = AUDIO_HW_IDLE;
@@ -1388,15 +1389,19 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
status_t status;
PlaybackThread *thread = NULL;
- struct audio_config config = {
- sample_rate: pSamplingRate ? *pSamplingRate : 0,
- channel_mask: pChannelMask ? *pChannelMask : 0,
- format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
- };
+ struct audio_config config;
+ config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
+ config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
+ config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
+ if (offloadInfo) {
+ config.offload_info = *offloadInfo;
+ }
+
audio_stream_out_t *outStream = NULL;
AudioHwDevice *outHwDev;
@@ -1591,11 +1596,11 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
{
status_t status;
RecordThread *thread = NULL;
- struct audio_config config = {
- sample_rate: pSamplingRate ? *pSamplingRate : 0,
- channel_mask: pChannelMask ? *pChannelMask : 0,
- format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
- };
+ struct audio_config config;
+ config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
+ config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
+ config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
+
uint32_t reqSamplingRate = config.sample_rate;
audio_format_t reqFormat = config.format;
audio_channel_mask_t reqChannels = config.channel_mask;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 05dbab1..b640b31 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -160,7 +160,8 @@ public:
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
- audio_output_flags_t flags);
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo);
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2);
@@ -406,6 +407,8 @@ private:
int target);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
+ virtual status_t setParameters(const String8& keyValuePairs);
private:
const sp<PlaybackThread::Track> mTrack;
};
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 2706880..fd4431c 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -222,15 +222,16 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
if (mpAudioPolicy == NULL) {
return 0;
}
ALOGV("getOutput()");
Mutex::Autolock _l(mLock);
- return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channelMask,
- flags);
+ return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate,
+ format, channelMask, flags, offloadInfo);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -1055,6 +1056,11 @@ int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
}
+bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
+{
+ return false; // stub function
+}
+
// ----------------------------------------------------------------------------
// Audio pre-processing configuration
// ----------------------------------------------------------------------------
@@ -1387,7 +1393,8 @@ static audio_io_handle_t aps_open_output_on_module(void *service,
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask,
uint32_t *pLatencyMs,
- audio_output_flags_t flags)
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 53238fa..e723c47 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -67,7 +67,8 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
audio_channel_mask_t channelMask = 0,
audio_output_flags_t flags =
- AUDIO_OUTPUT_FLAG_NONE);
+ AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session = 0);
@@ -136,6 +137,7 @@ public:
virtual status_t startTone(audio_policy_tone_t tone, audio_stream_type_t stream);
virtual status_t stopTone();
virtual status_t setVoiceVolume(float volume, int delayMs = 0);
+ virtual bool isOffloadSupported(const audio_offload_info_t &config);
private:
AudioPolicyService() ANDROID_API;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index bfc197c..f0dbee3 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -250,6 +250,10 @@ void AudioFlinger::TrackHandle::pause() {
mTrack->pause();
}
+status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
+ return INVALID_OPERATION; // stub function
+}
+
status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
{
return mTrack->attachAuxEffect(EffectId);