summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioTrack.cpp21
-rw-r--r--media/libmedia/AudioTrackShared.cpp4
-rw-r--r--media/libmedia/IAudioFlinger.cpp54
-rw-r--r--media/libmedia/IAudioPolicyService.cpp26
-rw-r--r--media/libmedia/ICrypto.cpp23
-rw-r--r--media/libmedia/IEffect.cpp27
-rw-r--r--media/libmedia/IMediaPlayer.cpp34
-rw-r--r--media/libmedia/IMediaRecorder.cpp16
-rw-r--r--media/libmedia/IOMX.cpp6
-rwxr-xr-x[-rw-r--r--]media/libmedia/MediaProfiles.cpp33
-rw-r--r--media/libmedia/Visualizer.cpp8
-rw-r--r--media/libmedia/mediaplayer.cpp64
-rwxr-xr-x[-rw-r--r--]media/libmedia/mediarecorder.cpp28
13 files changed, 283 insertions, 61 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 3d9847c..0541f21 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -528,6 +528,15 @@ status_t AudioTrack::start()
mTimestampStartupGlitchReported = false;
mRetrogradeMotionReported = false;
+ // If previousState == STATE_STOPPED, we reactivate markers (mMarkerPosition != 0)
+ // as the position is reset to 0. This is legacy behavior. This is not done
+ // in stop() to avoid a race condition where the last marker event is issued twice.
+ // Note: the if is technically unnecessary because previousState == STATE_FLUSHED
+ // is only for streaming tracks, and mMarkerReached is already set to false.
+ if (previousState == STATE_STOPPED) {
+ mMarkerReached = false;
+ }
+
// For offloaded tracks, we don't know if the hardware counters are really zero here,
// since the flush is asynchronous and stop may not fully drain.
// We save the time when the track is started to later verify whether
@@ -603,9 +612,9 @@ void AudioTrack::stop()
mProxy->interrupt();
mAudioTrack->stop();
- // the playback head position will reset to 0, so if a marker is set, we need
- // to activate it again
- mMarkerReached = false;
+
+ // Note: legacy handling - stop does not clear playback marker
+ // and periodic update counter, but flush does for streaming tracks.
if (mSharedBuffer != 0) {
// clear buffer position and loop count.
@@ -708,7 +717,7 @@ status_t AudioTrack::setVolume(float left, float right)
mProxy->setVolumeLR(gain_minifloat_pack(gain_from_float(left), gain_from_float(right)));
- if (isOffloaded_l()) {
+ if (isOffloaded_l() && mAudioTrack != NULL) {
mAudioTrack->signal();
}
return NO_ERROR;
@@ -833,13 +842,13 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
}
// Check resampler ratios are within bounds
- if (effectiveRate > mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
+ if ((uint64_t)effectiveRate > (uint64_t)mSampleRate * (uint64_t)AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
ALOGV("setPlaybackRate(%f, %f) failed. Resample rate exceeds max accepted value",
playbackRate.mSpeed, playbackRate.mPitch);
return BAD_VALUE;
}
- if (effectiveRate * AUDIO_RESAMPLER_UP_RATIO_MAX < mSampleRate) {
+ if ((uint64_t)effectiveRate * (uint64_t)AUDIO_RESAMPLER_UP_RATIO_MAX < (uint64_t)mSampleRate) {
ALOGV("setPlaybackRate(%f, %f) failed. Resample rate below min accepted value",
playbackRate.mSpeed, playbackRate.mPitch);
return BAD_VALUE;
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 6a51a76..0f8e6d6 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -38,7 +38,7 @@ size_t clampToSize(T x) {
// In general, this means (new_self) returned is max(self, other) + 1.
static uint32_t incrementSequence(uint32_t self, uint32_t other) {
- int32_t diff = self - other;
+ int32_t diff = (int32_t) self - (int32_t) other;
if (diff >= 0 && diff < INT32_MAX) {
return self + 1; // we're already ahead of other.
}
@@ -893,7 +893,7 @@ ssize_t StaticAudioTrackServerProxy::pollPosition()
if (mObserver.poll(state)) {
StaticAudioTrackState trystate = mState;
bool result;
- const int32_t diffSeq = state.mLoopSequence - state.mPositionSequence;
+ const int32_t diffSeq = (int32_t) state.mLoopSequence - (int32_t) state.mPositionSequence;
if (diffSeq < 0) {
result = updateStateWithLoop(&trystate, state) == OK &&
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index a3f014b..0bf503a 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -937,7 +937,7 @@ status_t BnAudioFlinger::onTransact(
pid_t tid = (pid_t) data.readInt32();
int sessionId = data.readInt32();
int clientUid = data.readInt32();
- status_t status;
+ status_t status = NO_ERROR;
sp<IAudioTrack> track;
if ((haveSharedBuffer && (buffer == 0)) ||
((buffer != 0) && (buffer->pointer() == NULL))) {
@@ -972,7 +972,7 @@ status_t BnAudioFlinger::onTransact(
size_t notificationFrames = data.readInt64();
sp<IMemory> cblk;
sp<IMemory> buffers;
- status_t status;
+ status_t status = NO_ERROR;
sp<IAudioRecord> record = openRecord(input,
sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid,
clientUid, &sessionId, &notificationFrames, cblk, buffers, &status);
@@ -1104,13 +1104,15 @@ status_t BnAudioFlinger::onTransact(
case OPEN_OUTPUT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
- audio_config_t config;
- data.read(&config, sizeof(audio_config_t));
+ audio_config_t config = {};
+ if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
+ ALOGE("b/23905951");
+ }
audio_devices_t devices = (audio_devices_t)data.readInt32();
String8 address(data.readString8());
audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
- uint32_t latencyMs;
- audio_io_handle_t output;
+ uint32_t latencyMs = 0;
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = openOutput(module, &output, &config,
&devices, address, &latencyMs, flags);
ALOGV("OPEN_OUTPUT output, %d", output);
@@ -1149,8 +1151,10 @@ status_t BnAudioFlinger::onTransact(
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
- audio_config_t config;
- data.read(&config, sizeof(audio_config_t));
+ audio_config_t config = {};
+ if (data.read(&config, sizeof(audio_config_t)) != NO_ERROR) {
+ ALOGE("b/23905951");
+ }
audio_devices_t device = (audio_devices_t)data.readInt32();
String8 address(data.readString8());
audio_source_t source = (audio_source_t)data.readInt32();
@@ -1186,8 +1190,8 @@ status_t BnAudioFlinger::onTransact(
case GET_RENDER_POSITION: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
- uint32_t halFrames;
- uint32_t dspFrames;
+ uint32_t halFrames = 0;
+ uint32_t dspFrames = 0;
status_t status = getRenderPosition(&halFrames, &dspFrames, output);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1223,7 +1227,7 @@ status_t BnAudioFlinger::onTransact(
} break;
case QUERY_NUM_EFFECTS: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- uint32_t numEffects;
+ uint32_t numEffects = 0;
status_t status = queryNumberEffects(&numEffects);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1233,7 +1237,7 @@ status_t BnAudioFlinger::onTransact(
}
case QUERY_EFFECT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- effect_descriptor_t desc;
+ effect_descriptor_t desc = {};
status_t status = queryEffect(data.readInt32(), &desc);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1245,7 +1249,7 @@ status_t BnAudioFlinger::onTransact(
CHECK_INTERFACE(IAudioFlinger, data, reply);
effect_uuid_t uuid;
data.read(&uuid, sizeof(effect_uuid_t));
- effect_descriptor_t desc;
+ effect_descriptor_t desc = {};
status_t status = getEffectDescriptor(&uuid, &desc);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1255,16 +1259,18 @@ status_t BnAudioFlinger::onTransact(
}
case CREATE_EFFECT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(effect_descriptor_t)) != NO_ERROR) {
+ ALOGE("b/23905951");
+ }
sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
int32_t priority = data.readInt32();
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
int sessionId = data.readInt32();
const String16 opPackageName = data.readString16();
- status_t status;
- int id;
- int enabled;
+ status_t status = NO_ERROR;
+ int id = 0;
+ int enabled = 0;
sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
opPackageName, &status, &id, &enabled);
@@ -1333,8 +1339,10 @@ status_t BnAudioFlinger::onTransact(
} break;
case GET_AUDIO_PORT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- struct audio_port port;
- data.read(&port, sizeof(struct audio_port));
+ struct audio_port port = {};
+ if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) {
+ ALOGE("b/23905951");
+ }
status_t status = getAudioPort(&port);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1346,8 +1354,10 @@ status_t BnAudioFlinger::onTransact(
CHECK_INTERFACE(IAudioFlinger, data, reply);
struct audio_patch patch;
data.read(&patch, sizeof(struct audio_patch));
- audio_patch_handle_t handle;
- data.read(&handle, sizeof(audio_patch_handle_t));
+ audio_patch_handle_t handle = {};
+ if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
+ ALOGE("b/23905951");
+ }
status_t status = createAudioPatch(&patch, &handle);
reply->writeInt32(status);
if (status == NO_ERROR) {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 3348441..76b5924 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -877,7 +877,7 @@ status_t BnAudioPolicyService::onTransact(
if (hasOffloadInfo) {
data.read(&offloadInfo, sizeof(audio_offload_info_t));
}
- audio_io_handle_t output;
+ audio_io_handle_t output = 0;
status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
&output, session, &stream, uid,
samplingRate, format, channelMask,
@@ -932,7 +932,7 @@ status_t BnAudioPolicyService::onTransact(
audio_channel_mask_t channelMask = data.readInt32();
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
- audio_io_handle_t input;
+ audio_io_handle_t input = {};
status_t status = getInputForAttr(&attr, &input, session, uid,
samplingRate, format, channelMask,
flags, selectedDeviceId);
@@ -994,7 +994,7 @@ status_t BnAudioPolicyService::onTransact(
audio_stream_type_t stream =
static_cast <audio_stream_type_t>(data.readInt32());
audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
- int index;
+ int index = 0;
status_t status = getStreamVolumeIndex(stream, &index, device);
reply->writeInt32(index);
reply->writeInt32(static_cast <uint32_t>(status));
@@ -1148,8 +1148,10 @@ status_t BnAudioPolicyService::onTransact(
case GET_AUDIO_PORT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port port;
- data.read(&port, sizeof(struct audio_port));
+ struct audio_port port = {};
+ if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) {
+ ALOGE("b/23912202");
+ }
status_t status = getAudioPort(&port);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1162,8 +1164,10 @@ status_t BnAudioPolicyService::onTransact(
CHECK_INTERFACE(IAudioPolicyService, data, reply);
struct audio_patch patch;
data.read(&patch, sizeof(struct audio_patch));
- audio_patch_handle_t handle;
- data.read(&handle, sizeof(audio_patch_handle_t));
+ audio_patch_handle_t handle = {};
+ if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
+ ALOGE("b/23912202");
+ }
status_t status = createAudioPatch(&patch, &handle);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1238,9 +1242,9 @@ status_t BnAudioPolicyService::onTransact(
CHECK_INTERFACE(IAudioPolicyService, data, reply);
sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(
data.readStrongBinder());
- audio_session_t session;
- audio_io_handle_t ioHandle;
- audio_devices_t device;
+ audio_session_t session = {};
+ audio_io_handle_t ioHandle = {};
+ audio_devices_t device = {};
status_t status = acquireSoundTriggerSession(&session, &ioHandle, &device);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1292,7 +1296,7 @@ status_t BnAudioPolicyService::onTransact(
data.read(&source, sizeof(struct audio_port_config));
audio_attributes_t attributes;
data.read(&attributes, sizeof(audio_attributes_t));
- audio_io_handle_t handle;
+ audio_io_handle_t handle = {};
status_t status = startAudioSource(&source, &attributes, &handle);
reply->writeInt32(status);
reply->writeInt32(handle);
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 8f05936..5d822cf 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -301,14 +301,31 @@ status_t BnCrypto::onTransact(
secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
AVMediaUtils::get()->readCustomData(&data, &secureBufferId);
} else {
- dstPtr = malloc(totalSize);
- CHECK(dstPtr != NULL);
+ dstPtr = calloc(1, totalSize);
}
AString errorDetailMsg;
ssize_t result;
- if (offset + totalSize > sharedBuffer->size()) {
+ size_t sumSubsampleSizes = 0;
+ bool overflow = false;
+ for (int32_t i = 0; i < numSubSamples; ++i) {
+ CryptoPlugin::SubSample &ss = subSamples[i];
+ if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfEncryptedData) {
+ sumSubsampleSizes += ss.mNumBytesOfEncryptedData;
+ } else {
+ overflow = true;
+ }
+ if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfClearData) {
+ sumSubsampleSizes += ss.mNumBytesOfClearData;
+ } else {
+ overflow = true;
+ }
+ }
+
+ if (overflow || sumSubsampleSizes != totalSize) {
+ result = -EINVAL;
+ } else if (offset + totalSize > sharedBuffer->size()) {
result = -EINVAL;
} else {
result = decrypt(
diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp
index 761b243..faf5795 100644
--- a/media/libmedia/IEffect.cpp
+++ b/media/libmedia/IEffect.cpp
@@ -85,13 +85,15 @@ public:
data.writeInt32(size);
status_t status = remote()->transact(COMMAND, data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
if (status != NO_ERROR) {
if (pReplySize != NULL)
*pReplySize = 0;
return status;
}
- status = reply.readInt32();
size = reply.readInt32();
if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
reply.read(pReplyData, size);
@@ -155,6 +157,10 @@ status_t BnEffect::onTransact(
char *cmd = NULL;
if (cmdSize) {
cmd = (char *)calloc(cmdSize, 1);
+ if (cmd == NULL) {
+ reply->writeInt32(NO_MEMORY);
+ return NO_ERROR;
+ }
data.read(cmd, cmdSize);
}
uint32_t replySize = data.readInt32();
@@ -162,15 +168,22 @@ status_t BnEffect::onTransact(
char *resp = NULL;
if (replySize) {
resp = (char *)calloc(replySize, 1);
+ if (resp == NULL) {
+ free(cmd);
+ reply->writeInt32(NO_MEMORY);
+ return NO_ERROR;
+ }
}
status_t status = command(cmdCode, cmdSize, cmd, &replySz, resp);
reply->writeInt32(status);
- if (replySz < replySize) {
- replySize = replySz;
- }
- reply->writeInt32(replySize);
- if (replySize) {
- reply->write(resp, replySize);
+ if (status == NO_ERROR) {
+ if (replySz < replySize) {
+ replySize = replySz;
+ }
+ reply->writeInt32(replySize);
+ if (replySize) {
+ reply->write(resp, replySize);
+ }
}
if (cmd) {
free(cmd);
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 7387a79..bad84b7 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -67,6 +67,8 @@ enum {
SET_RETRANSMIT_ENDPOINT,
GET_RETRANSMIT_ENDPOINT,
SET_NEXT_PLAYER,
+ SUSPEND,
+ RESUME,
};
class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -419,6 +421,22 @@ public:
return err;
}
+
+ status_t suspend()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ remote()->transact(SUSPEND, data, &reply);
+ return reply.readInt32();
+ }
+
+ status_t resume()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ remote()->transact(RESUME, data, &reply);
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -566,7 +584,7 @@ status_t BnMediaPlayer::onTransact(
} break;
case GET_CURRENT_POSITION: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- int msec;
+ int msec = 0;
status_t ret = getCurrentPosition(&msec);
reply->writeInt32(msec);
reply->writeInt32(ret);
@@ -574,7 +592,7 @@ status_t BnMediaPlayer::onTransact(
} break;
case GET_DURATION: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
- int msec;
+ int msec = 0;
status_t ret = getDuration(&msec);
reply->writeInt32(msec);
reply->writeInt32(ret);
@@ -682,6 +700,18 @@ status_t BnMediaPlayer::onTransact(
return NO_ERROR;
} break;
+ case SUSPEND: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ status_t ret = suspend();
+ reply->writeInt32(ret);
+ return NO_ERROR;
+ } break;
+ case RESUME: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ status_t ret = resume();
+ reply->writeInt32(ret);
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index ee3b584..4711c1b 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -39,6 +39,7 @@ enum {
QUERY_SURFACE_MEDIASOURCE,
RESET,
STOP,
+ PAUSE,
START,
PREPARE,
GET_MAX_AMPLITUDE,
@@ -258,6 +259,15 @@ public:
return reply.readInt32();
}
+ status_t pause()
+ {
+ ALOGV("pause");
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ remote()->transact(PAUSE, data, &reply);
+ return reply.readInt32();
+ }
+
status_t stop()
{
ALOGV("stop");
@@ -334,6 +344,12 @@ status_t BnMediaRecorder::onTransact(
reply->writeInt32(stop());
return NO_ERROR;
} break;
+ case PAUSE: {
+ ALOGV("PAUSE");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ reply->writeInt32(pause());
+ return NO_ERROR;
+ } break;
case START: {
ALOGV("START");
CHECK_INTERFACE(IMediaRecorder, data, reply);
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index ac2e872..5356494 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -965,6 +965,12 @@ status_t BnOMX::onTransact(
node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
+ if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
+ ALOGE("b/24310423");
+ reply->writeInt32(INVALID_OPERATION);
+ return NO_ERROR;
+ }
+
size_t size = data.readInt64();
buffer_id buffer;
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 8af0ce8..87ec309 100644..100755
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -1,4 +1,6 @@
/*
+** Copyright (c) 2014, The Linux Foundation. All rights reserved.
+** Not a Contribution.
**
** Copyright 2010, The Android Open Source Project
**
@@ -137,6 +139,8 @@ MediaProfiles::logVideoEncoderCap(const MediaProfiles::VideoEncoderCap& cap UNUS
ALOGV("frame width: min = %d and max = %d", cap.mMinFrameWidth, cap.mMaxFrameWidth);
ALOGV("frame height: min = %d and max = %d", cap.mMinFrameHeight, cap.mMaxFrameHeight);
ALOGV("frame rate: min = %d and max = %d", cap.mMinFrameRate, cap.mMaxFrameRate);
+ ALOGV("max HFR width: = %d max HFR height: = %d", cap.mMaxHFRFrameWidth, cap.mMaxHFRFrameHeight);
+ ALOGV("max HFR mode: = %d", cap.mMaxHFRMode);
}
/*static*/ void
@@ -272,10 +276,23 @@ MediaProfiles::createVideoEncoderCap(const char **atts)
const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
CHECK(codec != -1);
+ int maxHFRWidth = 0, maxHFRHeight = 0, maxHFRMode = 0;
+ // Check if there are enough (start through end) attributes in the
+ // 0-terminated list, to include our additional HFR params. Then check
+ // if each of those match the expected names.
+ if (atts[20] && atts[21] && !strcmp("maxHFRFrameWidth", atts[20]) &&
+ atts[22] && atts[23] && !strcmp("maxHFRFrameHeight", atts[22]) &&
+ atts[24] && atts[25] && !strcmp("maxHFRMode", atts[24])) {
+ maxHFRWidth = atoi(atts[21]);
+ maxHFRHeight = atoi(atts[23]);
+ maxHFRMode = atoi(atts[25]);
+ }
+
MediaProfiles::VideoEncoderCap *cap =
new MediaProfiles::VideoEncoderCap(static_cast<video_encoder>(codec),
atoi(atts[5]), atoi(atts[7]), atoi(atts[9]), atoi(atts[11]), atoi(atts[13]),
- atoi(atts[15]), atoi(atts[17]), atoi(atts[19]));
+ atoi(atts[15]), atoi(atts[17]), atoi(atts[19]),
+ maxHFRWidth, maxHFRHeight, maxHFRMode);
logVideoEncoderCap(*cap);
return cap;
}
@@ -629,14 +646,14 @@ MediaProfiles::getInstance()
MediaProfiles::createDefaultH263VideoEncoderCap()
{
return new MediaProfiles::VideoEncoderCap(
- VIDEO_ENCODER_H263, 192000, 420000, 176, 352, 144, 288, 1, 20);
+ VIDEO_ENCODER_H263, 192000, 420000, 176, 352, 144, 288, 1, 20, 0, 0, 0);
}
/*static*/ MediaProfiles::VideoEncoderCap*
MediaProfiles::createDefaultM4vVideoEncoderCap()
{
return new MediaProfiles::VideoEncoderCap(
- VIDEO_ENCODER_MPEG_4_SP, 192000, 420000, 176, 352, 144, 288, 1, 20);
+ VIDEO_ENCODER_MPEG_4_SP, 192000, 420000, 176, 352, 144, 288, 1, 20, 0, 0, 0);
}
@@ -791,6 +808,7 @@ MediaProfiles::createDefaultCamcorderProfiles(MediaProfiles *profiles)
MediaProfiles::createDefaultAudioEncoders(MediaProfiles *profiles)
{
profiles->mAudioEncoders.add(createDefaultAmrNBEncoderCap());
+ profiles->mAudioEncoders.add(createDefaultAacEncoderCap());
profiles->mAudioEncoders.add(createDefaultLpcmEncoderCap());
}
@@ -826,6 +844,12 @@ MediaProfiles::createDefaultAmrNBEncoderCap()
AUDIO_ENCODER_AMR_NB, 5525, 12200, 8000, 8000, 1, 1);
}
+/*static*/ MediaProfiles::AudioEncoderCap*
+MediaProfiles::createDefaultAacEncoderCap()
+{
+ return new MediaProfiles::AudioEncoderCap(
+ AUDIO_ENCODER_AAC, 64000, 156000, 8000, 48000, 1, 2);
+}
/*static*/ MediaProfiles::AudioEncoderCap*
MediaProfiles::createDefaultLpcmEncoderCap()
@@ -949,6 +973,9 @@ int MediaProfiles::getVideoEncoderParamByName(const char *name, video_encoder co
if (!strcmp("enc.vid.bps.max", name)) return mVideoEncoders[index]->mMaxBitRate;
if (!strcmp("enc.vid.fps.min", name)) return mVideoEncoders[index]->mMinFrameRate;
if (!strcmp("enc.vid.fps.max", name)) return mVideoEncoders[index]->mMaxFrameRate;
+ if (!strcmp("enc.vid.hfr.width.max", name)) return mVideoEncoders[index]->mMaxHFRFrameWidth;
+ if (!strcmp("enc.vid.hfr.height.max", name)) return mVideoEncoders[index]->mMaxHFRFrameHeight;
+ if (!strcmp("enc.vid.hfr.mode.max", name)) return mVideoEncoders[index]->mMaxHFRMode;
ALOGE("The given video encoder param name %s is not found", name);
return -1;
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index f5c1b1f..8d83c1b 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -94,6 +94,14 @@ status_t Visualizer::setEnabled(bool enabled)
return status;
}
+void Visualizer::cancelCaptureCallBack()
+{
+ sp<CaptureThread> t = mCaptureThread;
+ if (t != 0) {
+ t->requestExitAndWait();
+ }
+}
+
status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags,
uint32_t rate, bool force)
{
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 502ab2d..3c6bef3 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -333,6 +333,9 @@ status_t MediaPlayer::start()
ALOGV("playback completed immediately following start()");
}
}
+ } else if ( (mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_SUSPENDED) ) {
+ ALOGV("start while suspended, so ignore this start");
+ ret = NO_ERROR;
} else {
ALOGE("start called in state %d", mCurrentState);
ret = INVALID_OPERATION;
@@ -395,6 +398,10 @@ bool MediaPlayer::isPlaying()
ALOGE("internal/external state mismatch corrected");
mCurrentState = MEDIA_PLAYER_STARTED;
}
+ if ((mCurrentState & MEDIA_PLAYER_PLAYBACK_COMPLETE) && temp) {
+ ALOGE("internal/external state mismatch corrected");
+ mCurrentState = MEDIA_PLAYER_STARTED;
+ }
return temp;
}
ALOGV("isPlaying: no active player");
@@ -484,7 +491,8 @@ status_t MediaPlayer::getDuration_l(int *msec)
{
ALOGV("getDuration_l");
bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
- MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
+ MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE |
+ MEDIA_PLAYER_SUSPENDED));
if (mPlayer != 0 && isValidState) {
int durationMs;
status_t ret = mPlayer->getDuration(&durationMs);
@@ -514,7 +522,7 @@ status_t MediaPlayer::seekTo_l(int msec)
{
ALOGV("seekTo %d", msec);
if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
- MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
+ MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_SUSPENDED) ) ) {
if ( msec < 0 ) {
ALOGW("Attempt to seek to invalid position: %d", msec);
msec = 0;
@@ -935,4 +943,54 @@ status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
}
-} // namespace android
+status_t MediaPlayer::suspend() {
+ ALOGV("MediaPlayer::suspend()");
+ Mutex::Autolock _l(mLock);
+ if (mPlayer == NULL) {
+ ALOGE("mPlayer = NULL");
+ return NO_INIT;
+ }
+
+ bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_SUSPENDED));
+
+ if (!isValidState) {
+ ALOGE("suspend while in a invalid state = %d", mCurrentState);
+ return UNKNOWN_ERROR;
+ }
+
+ status_t ret = mPlayer->suspend();
+
+ if (OK != ret) {
+ ALOGE("MediaPlayer::suspend() return with error ret = %d", ret);
+ return ret;
+ }
+ mCurrentState = MEDIA_PLAYER_SUSPENDED;
+ return OK;
+}
+
+status_t MediaPlayer::resume() {
+ ALOGV("MediaPlayer::resume()");
+ Mutex::Autolock _l(mLock);
+ if (mPlayer == NULL) {
+ ALOGE("mPlayer == NULL");
+ return NO_INIT;
+ }
+
+ bool isValidState = (mCurrentState == MEDIA_PLAYER_SUSPENDED);
+
+ if (!isValidState) {
+ ALOGE("resume while in a invalid state = %d", mCurrentState);
+ return UNKNOWN_ERROR;
+ }
+
+ status_t ret = mPlayer->resume();
+
+ if (OK != ret) {
+ ALOGE("MediaPlayer::resume() return with error ret = %d", ret);
+ return ret;
+ }
+ mCurrentState = MEDIA_PLAYER_PREPARED;
+ return OK;
+}
+
+}; // namespace android
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 8bbd8f1..8b7b171 100644..100755
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -482,7 +482,7 @@ status_t MediaRecorder::start()
ALOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
}
- if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
+ if (!(mCurrentState & (MEDIA_RECORDER_PREPARED | MEDIA_RECORDER_PAUSED))) {
ALOGE("start called in an invalid state: %d", mCurrentState);
return INVALID_OPERATION;
}
@@ -497,6 +497,29 @@ status_t MediaRecorder::start()
return ret;
}
+status_t MediaRecorder::pause()
+{
+ ALOGV("pause");
+ if (mMediaRecorder == NULL) {
+ ALOGE("media recorder is not initialized yet");
+ return INVALID_OPERATION;
+ }
+ if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
+ ALOGE("pause called in an invalid state: %d", mCurrentState);
+ return INVALID_OPERATION;
+ }
+
+ status_t ret = mMediaRecorder->pause();
+ if (OK != ret) {
+ ALOGE("pause failed: %d", ret);
+ mCurrentState = MEDIA_RECORDER_ERROR;
+ return ret;
+ }
+
+ mCurrentState = MEDIA_RECORDER_PAUSED;
+ return ret;
+}
+
status_t MediaRecorder::stop()
{
ALOGV("stop");
@@ -504,7 +527,7 @@ status_t MediaRecorder::stop()
ALOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
}
- if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
+ if (!(mCurrentState & (MEDIA_RECORDER_RECORDING | MEDIA_RECORDER_PAUSED))) {
ALOGE("stop called in an invalid state: %d", mCurrentState);
return INVALID_OPERATION;
}
@@ -540,6 +563,7 @@ status_t MediaRecorder::reset()
ret = OK;
break;
+ case MEDIA_RECORDER_PAUSED:
case MEDIA_RECORDER_RECORDING:
case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
case MEDIA_RECORDER_PREPARED: