df9b81ced4
The visualizer enables application to retrieve part of the currently playing audio for visualization purpose. It is not an audio recording interface and only returns partial and low quality audio content as a waveform or a frequency representation (FFT). Removed temporary hack made in MediaPlayer for animated wall papers based on audio visualization (snoop() method. This commit also includes a change in AudioEffect class: - the enable()/disable() methods have been replaced bya more standard setEnabled() method. - some fixes in javadoc Change-Id: Id092a1340e9e38dae68646ade7be054e3a36980e
243 lines
8.8 KiB
C++
243 lines
8.8 KiB
C++
/*
|
|
**
|
|
** Copyright 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 <stdint.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <binder/Parcel.h>
|
|
#include <binder/IMemory.h>
|
|
#include <media/IMediaPlayerService.h>
|
|
#include <media/IMediaRecorder.h>
|
|
#include <media/IOMX.h>
|
|
|
|
#include <utils/Errors.h> // for status_t
|
|
|
|
namespace android {
|
|
|
|
enum {
|
|
CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
|
|
CREATE_FD,
|
|
DECODE_URL,
|
|
DECODE_FD,
|
|
CREATE_MEDIA_RECORDER,
|
|
CREATE_METADATA_RETRIEVER,
|
|
GET_OMX
|
|
};
|
|
|
|
class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
|
|
{
|
|
public:
|
|
BpMediaPlayerService(const sp<IBinder>& impl)
|
|
: BpInterface<IMediaPlayerService>(impl)
|
|
{
|
|
}
|
|
|
|
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid)
|
|
{
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
data.writeInt32(pid);
|
|
remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
|
|
return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
|
|
}
|
|
|
|
virtual sp<IMediaPlayer> create(
|
|
pid_t pid, const sp<IMediaPlayerClient>& client,
|
|
const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) {
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
data.writeInt32(pid);
|
|
data.writeStrongBinder(client->asBinder());
|
|
data.writeCString(url);
|
|
|
|
if (headers == NULL) {
|
|
data.writeInt32(0);
|
|
} else {
|
|
// serialize the headers
|
|
data.writeInt32(headers->size());
|
|
for (size_t i = 0; i < headers->size(); ++i) {
|
|
data.writeString8(headers->keyAt(i));
|
|
data.writeString8(headers->valueAt(i));
|
|
}
|
|
}
|
|
data.writeInt32(audioSessionId);
|
|
|
|
remote()->transact(CREATE_URL, data, &reply);
|
|
|
|
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
|
|
}
|
|
|
|
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid)
|
|
{
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
data.writeInt32(pid);
|
|
remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
|
|
return interface_cast<IMediaRecorder>(reply.readStrongBinder());
|
|
}
|
|
|
|
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd,
|
|
int64_t offset, int64_t length, int audioSessionId)
|
|
{
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
data.writeInt32(pid);
|
|
data.writeStrongBinder(client->asBinder());
|
|
data.writeFileDescriptor(fd);
|
|
data.writeInt64(offset);
|
|
data.writeInt64(length);
|
|
data.writeInt32(audioSessionId);
|
|
|
|
remote()->transact(CREATE_FD, data, &reply);
|
|
|
|
return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
|
|
}
|
|
|
|
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
|
|
{
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
data.writeCString(url);
|
|
remote()->transact(DECODE_URL, data, &reply);
|
|
*pSampleRate = uint32_t(reply.readInt32());
|
|
*pNumChannels = reply.readInt32();
|
|
*pFormat = reply.readInt32();
|
|
return interface_cast<IMemory>(reply.readStrongBinder());
|
|
}
|
|
|
|
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
|
|
{
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
data.writeFileDescriptor(fd);
|
|
data.writeInt64(offset);
|
|
data.writeInt64(length);
|
|
remote()->transact(DECODE_FD, data, &reply);
|
|
*pSampleRate = uint32_t(reply.readInt32());
|
|
*pNumChannels = reply.readInt32();
|
|
*pFormat = reply.readInt32();
|
|
return interface_cast<IMemory>(reply.readStrongBinder());
|
|
}
|
|
|
|
virtual sp<IOMX> getOMX() {
|
|
Parcel data, reply;
|
|
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
|
|
remote()->transact(GET_OMX, data, &reply);
|
|
return interface_cast<IOMX>(reply.readStrongBinder());
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
status_t BnMediaPlayerService::onTransact(
|
|
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
|
|
{
|
|
switch(code) {
|
|
case CREATE_URL: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
pid_t pid = data.readInt32();
|
|
sp<IMediaPlayerClient> client =
|
|
interface_cast<IMediaPlayerClient>(data.readStrongBinder());
|
|
const char* url = data.readCString();
|
|
|
|
KeyedVector<String8, String8> headers;
|
|
int32_t numHeaders = data.readInt32();
|
|
for (int i = 0; i < numHeaders; ++i) {
|
|
String8 key = data.readString8();
|
|
String8 value = data.readString8();
|
|
headers.add(key, value);
|
|
}
|
|
int audioSessionId = data.readInt32();
|
|
|
|
sp<IMediaPlayer> player = create(
|
|
pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId);
|
|
|
|
reply->writeStrongBinder(player->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
case CREATE_FD: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
pid_t pid = data.readInt32();
|
|
sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
|
|
int fd = dup(data.readFileDescriptor());
|
|
int64_t offset = data.readInt64();
|
|
int64_t length = data.readInt64();
|
|
int audioSessionId = data.readInt32();
|
|
|
|
sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId);
|
|
reply->writeStrongBinder(player->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
case DECODE_URL: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
const char* url = data.readCString();
|
|
uint32_t sampleRate;
|
|
int numChannels;
|
|
int format;
|
|
sp<IMemory> player = decode(url, &sampleRate, &numChannels, &format);
|
|
reply->writeInt32(sampleRate);
|
|
reply->writeInt32(numChannels);
|
|
reply->writeInt32(format);
|
|
reply->writeStrongBinder(player->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
case DECODE_FD: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
int fd = dup(data.readFileDescriptor());
|
|
int64_t offset = data.readInt64();
|
|
int64_t length = data.readInt64();
|
|
uint32_t sampleRate;
|
|
int numChannels;
|
|
int format;
|
|
sp<IMemory> player = decode(fd, offset, length, &sampleRate, &numChannels, &format);
|
|
reply->writeInt32(sampleRate);
|
|
reply->writeInt32(numChannels);
|
|
reply->writeInt32(format);
|
|
reply->writeStrongBinder(player->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
case CREATE_MEDIA_RECORDER: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
pid_t pid = data.readInt32();
|
|
sp<IMediaRecorder> recorder = createMediaRecorder(pid);
|
|
reply->writeStrongBinder(recorder->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
case CREATE_METADATA_RETRIEVER: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
pid_t pid = data.readInt32();
|
|
sp<IMediaMetadataRetriever> retriever = createMetadataRetriever(pid);
|
|
reply->writeStrongBinder(retriever->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
case GET_OMX: {
|
|
CHECK_INTERFACE(IMediaPlayerService, data, reply);
|
|
sp<IOMX> omx = getOMX();
|
|
reply->writeStrongBinder(omx->asBinder());
|
|
return NO_ERROR;
|
|
} break;
|
|
default:
|
|
return BBinder::onTransact(code, data, reply, flags);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
}; // namespace android
|