Merge "Add memory heap checks for mediaserver and audioserver" into nyc-dev
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index f8b2f68..9aa0156 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -215,7 +215,7 @@
enc_meta->setInt32("width", width);
enc_meta->setInt32("height", height);
enc_meta->setInt32("sample-rate", kFramerate);
- enc_meta->setInt32("bit-rate", kVideoBitRate);
+ enc_meta->setInt32("bitrate", kVideoBitRate);
// enc_meta->setInt32("stride", width);
// enc_meta->setInt32("slice-height", height);
enc_meta->setInt32("i-frame-interval", kIFramesIntervalSec);
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 585ef59..2e6646a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -238,6 +238,7 @@
static status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 1ade4ba..984bc02 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -73,6 +73,7 @@
// reference and will release it when the track is destroyed.
// However on failure, the client is responsible for release.
audio_io_handle_t output,
+ pid_t pid,
pid_t tid, // -1 means unused, otherwise must be valid non-0
audio_session_t *sessionId,
int clientUid,
@@ -89,6 +90,7 @@
const String16& callingPackage,
size_t *pFrameCount,
track_flags_t *flags,
+ pid_t pid,
pid_t tid, // -1 means unused, otherwise must be valid non-0
int clientUid,
audio_session_t *sessionId,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 80437dc..0e9e3bc 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -81,6 +81,7 @@
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 3074910..8fc410d 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -38,7 +38,9 @@
const String16 &opPackageName,
uint32_t sampleRate,
uint32_t channels,
- uint32_t outSampleRate = 0);
+ uint32_t outSampleRate = 0,
+ uid_t uid = -1,
+ pid_t pid = -1);
status_t initCheck() const;
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index ba375a2..7b43f87 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -52,6 +52,8 @@
kKeyPcmEncoding = 'PCMe', // int32_t (audio encoding enum)
kKeyFrameRate = 'frmR', // int32_t (video frame rate fps)
kKeyBitRate = 'brte', // int32_t (bps)
+ kKeyMaxBitRate = 'mxBr', // int32_t (bps)
+ kKeyStreamHeader = 'stHd', // raw data
kKeyESDS = 'esds', // raw data
kKeyAACProfile = 'aacp', // int32_t
kKeyAVCC = 'avcc', // raw data
diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h
index 6606c58..03e2185 100644
--- a/include/media/stagefright/NuMediaExtractor.h
+++ b/include/media/stagefright/NuMediaExtractor.h
@@ -44,6 +44,11 @@
SAMPLE_FLAG_ENCRYPTED = 2,
};
+ // identical to IMediaExtractor::GetTrackMetaDataFlags
+ enum GetTrackFormatFlags {
+ kIncludeExtensiveMetaData = 1, // reads sample table and possibly stream headers
+ };
+
NuMediaExtractor();
status_t setDataSource(
@@ -56,7 +61,7 @@
status_t setDataSource(const sp<DataSource> &datasource);
size_t countTracks() const;
- status_t getTrackFormat(size_t index, sp<AMessage> *format) const;
+ status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
status_t getFileFormat(sp<AMessage> *format) const;
diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h
index 17631a0..01b3e3f 100644
--- a/include/media/stagefright/Utils.h
+++ b/include/media/stagefright/Utils.h
@@ -48,6 +48,11 @@
void convertMessageToMetaData(
const sp<AMessage> &format, sp<MetaData> &meta);
+// Returns a pointer to the next NAL start code in buffer of size |length| starting at |data|, or
+// a pointer to the end of the buffer if the start code is not found.
+// TODO: combine this with avc_utils::getNextNALUnit
+const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length);
+
AString MakeUserAgent();
// Convert a MIME type to a AudioSystem::audio_format
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 2976a5c..d9bb856 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -533,7 +533,8 @@
status = AudioSystem::getInputForAttr(&mAttributes, &input,
mSessionId,
// FIXME compare to AudioTrack
- IPCThreadState::self()->getCallingUid(),
+ mClientPid,
+ mClientUid,
mSampleRate, mFormat, mChannelMask,
mFlags, mSelectedDeviceId);
@@ -615,6 +616,7 @@
opPackageName,
&temp,
&trackFlags,
+ mClientPid,
tid,
mClientUid,
&mSessionId,
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index bbdf65e..808b3ab 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -836,6 +836,7 @@
status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
@@ -846,7 +847,8 @@
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
return aps->getInputForAttr(
- attr, input, session, uid, samplingRate, format, channelMask, flags, selectedDeviceId);
+ attr, input, session, pid, uid,
+ samplingRate, format, channelMask, flags, selectedDeviceId);
}
status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 22a5acd..f206f5c 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1401,6 +1401,7 @@
&trackFlags,
mSharedBuffer,
output,
+ mClientPid,
tid,
&mSessionId,
mClientUid,
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index aa75188..92e65e4 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -104,6 +104,7 @@
track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ pid_t pid,
pid_t tid,
audio_session_t *sessionId,
int clientUid,
@@ -128,6 +129,7 @@
data.writeInt32(false);
}
data.writeInt32((int32_t) output);
+ data.writeInt32((int32_t) pid);
data.writeInt32((int32_t) tid);
audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
if (sessionId != NULL) {
@@ -179,6 +181,7 @@
const String16& opPackageName,
size_t *pFrameCount,
track_flags_t *flags,
+ pid_t pid,
pid_t tid,
int clientUid,
audio_session_t *sessionId,
@@ -199,6 +202,7 @@
data.writeInt64(frameCount);
track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
data.writeInt32(lFlags);
+ data.writeInt32((int32_t) pid);
data.writeInt32((int32_t) tid);
data.writeInt32((int32_t) clientUid);
audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
@@ -950,6 +954,7 @@
buffer = interface_cast<IMemory>(data.readStrongBinder());
}
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
+ pid_t pid = (pid_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
audio_session_t sessionId = (audio_session_t) data.readInt32();
int clientUid = data.readInt32();
@@ -962,7 +967,7 @@
} else {
track = createTrack(
(audio_stream_type_t) streamType, sampleRate, format,
- channelMask, &frameCount, &flags, buffer, output, tid,
+ channelMask, &frameCount, &flags, buffer, output, pid, tid,
&sessionId, clientUid, &status);
LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
}
@@ -982,6 +987,7 @@
const String16& opPackageName = data.readString16();
size_t frameCount = data.readInt64();
track_flags_t flags = (track_flags_t) data.readInt32();
+ pid_t pid = (pid_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
int clientUid = data.readInt32();
audio_session_t sessionId = (audio_session_t) data.readInt32();
@@ -990,8 +996,9 @@
sp<IMemory> buffers;
status_t status = NO_ERROR;
sp<IAudioRecord> record = openRecord(input,
- sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid,
- clientUid, &sessionId, ¬ificationFrames, cblk, buffers, &status);
+ sampleRate, format, channelMask, opPackageName, &frameCount, &flags,
+ pid, tid, clientUid, &sessionId, ¬ificationFrames, cblk, buffers,
+ &status);
LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
reply->writeInt64(frameCount);
reply->writeInt32(flags);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 4ea67da..6405d6d 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -280,6 +280,7 @@
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
@@ -299,6 +300,7 @@
}
data.write(attr, sizeof(audio_attributes_t));
data.writeInt32(session);
+ data.writeInt32(pid);
data.writeInt32(uid);
data.writeInt32(samplingRate);
data.writeInt32(static_cast <uint32_t>(format));
@@ -959,6 +961,7 @@
audio_attributes_t attr;
data.read(&attr, sizeof(audio_attributes_t));
audio_session_t session = (audio_session_t)data.readInt32();
+ pid_t pid = (pid_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32();
uint32_t samplingRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
@@ -966,7 +969,7 @@
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_NONE;
- status_t status = getInputForAttr(&attr, &input, session, uid,
+ status_t status = getInputForAttr(&attr, &input, session, pid, uid,
samplingRate, format, channelMask,
flags, selectedDeviceId);
reply->writeInt32(status);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6114af8..97ba76b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -934,7 +934,9 @@
mOpPackageName,
sourceSampleRate,
mAudioChannels,
- mSampleRate);
+ mSampleRate,
+ mClientUid,
+ mClientPid);
status_t err = audioSource->initCheck();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1fbb957..87d64cd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -192,7 +192,6 @@
mSourceStarted(false),
mPaused(false),
mPausedByClient(true),
- mPendingBufferingFlag(PENDING_BUFFERING_FLAG_NONE),
mPausedForBuffering(false) {
clearFlushComplete();
}
@@ -723,10 +722,6 @@
onStart();
}
mPausedByClient = false;
- if (mPendingBufferingFlag != PENDING_BUFFERING_FLAG_NONE) {
- notifyListener(MEDIA_INFO, mPendingBufferingFlag, 0);
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
- }
break;
}
@@ -1218,8 +1213,6 @@
break;
}
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-
mDeferredActions.push_back(
new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
FLUSH_CMD_FLUSH /* video */));
@@ -1961,7 +1954,6 @@
}
mPreviousSeekTimeUs = seekTimeUs;
mSource->seekTo(seekTimeUs);
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
++mTimedTextGeneration;
// everything's flushed, continue playback.
@@ -2207,12 +2199,7 @@
case Source::kWhatBufferingStart:
{
- if (mPausedByClient) {
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_START;
- } else {
- notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
- }
+ notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
break;
}
@@ -2235,7 +2222,6 @@
case Source::kWhatBufferingEnd:
{
notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
- mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index e896ac6..7431532 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -183,12 +183,6 @@
FLUSH_CMD_SHUTDOWN,
};
- enum PendingBufferingFlag {
- PENDING_BUFFERING_FLAG_NONE = MEDIA_INFO_UNKNOWN,
- PENDING_BUFFERING_FLAG_START = MEDIA_INFO_BUFFERING_START,
- PENDING_BUFFERING_FLAG_END = MEDIA_INFO_BUFFERING_END,
- };
-
// Status of flush responses from the decoder and renderer.
bool mFlushComplete[2][2];
@@ -215,9 +209,6 @@
// still become true, when we pause internally due to buffering.
bool mPausedByClient;
- // Pending buffering flag which is not sent to client due to being paused.
- PendingBufferingFlag mPendingBufferingFlag;
-
// Pause state as requested by source (internally) due to buffering
bool mPausedForBuffering;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 4ae8e82..e59a498 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1770,7 +1770,7 @@
mime.c_str(), audioFormat);
int avgBitRate = -1;
- format->findInt32("bit-rate", &avgBitRate);
+ format->findInt32("bitrate", &avgBitRate);
int32_t aacProfile = -1;
if (audioFormat == AUDIO_FORMAT_AAC
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index c8b61ca..790c6da 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -51,7 +51,8 @@
AudioSource::AudioSource(
audio_source_t inputSource, const String16 &opPackageName,
- uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate)
+ uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
+ uid_t uid, pid_t pid)
: mStarted(false),
mSampleRate(sampleRate),
mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
@@ -91,7 +92,12 @@
(size_t) (bufCount * frameCount),
AudioRecordCallbackFunction,
this,
- frameCount /*notificationFrames*/);
+ frameCount /*notificationFrames*/,
+ AUDIO_SESSION_ALLOCATE,
+ AudioRecord::TRANSFER_DEFAULT,
+ AUDIO_INPUT_FLAG_NONE,
+ uid,
+ pid);
mInitCheck = mRecord->initCheck();
if (mInitCheck != OK) {
mRecord.clear();
diff --git a/media/libstagefright/ESDS.cpp b/media/libstagefright/ESDS.cpp
index 8fbb57c..c31720d 100644
--- a/media/libstagefright/ESDS.cpp
+++ b/media/libstagefright/ESDS.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "ESDS"
#include <utils/Log.h>
+#include <media/stagefright/Utils.h>
+
#include "include/ESDS.h"
#include <string.h>
@@ -194,12 +196,25 @@
return err;
}
+status_t ESDS::getBitRate(uint32_t *brateMax, uint32_t *brateAvg) const {
+ if (mInitCheck != OK) {
+ return mInitCheck;
+ }
+
+ *brateMax = mBitRateMax;
+ *brateAvg = mBitRateAvg;
+
+ return OK;
+};
+
status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
if (size < 13) {
return ERROR_MALFORMED;
}
mObjectTypeIndication = mData[offset];
+ mBitRateMax = U32_AT(mData + offset + 5);
+ mBitRateAvg = U32_AT(mData + offset + 9);
offset += 13;
size -= 13;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index f296d9a..f29ec11 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -51,6 +51,11 @@
namespace android {
+enum {
+ // max track header chunk to return
+ kMaxTrackHeaderSize = 32,
+};
+
class MPEG4Source : public MediaSource {
public:
// Caller retains ownership of both "dataSource" and "sampleTable".
@@ -476,6 +481,22 @@
((int64_t)sampleTime * 1000000) / track->timescale);
}
}
+
+ // MPEG2 tracks do not provide CSD, so read the stream header
+ if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
+ off64_t offset;
+ size_t size;
+ if (track->sampleTable->getMetaDataForSample(
+ 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
+ if (size > kMaxTrackHeaderSize) {
+ size = kMaxTrackHeaderSize;
+ }
+ uint8_t header[kMaxTrackHeaderSize];
+ if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
+ track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
+ }
+ }
+ }
}
}
@@ -536,6 +557,10 @@
}
if (psshsize > 0 && psshsize <= UINT32_MAX) {
char *buf = (char*)malloc(psshsize);
+ if (!buf) {
+ ALOGE("b/28471206");
+ return NO_MEMORY;
+ }
char *ptr = buf;
for (size_t i = 0; i < mPssh.size(); i++) {
memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
@@ -1738,12 +1763,42 @@
break;
}
+ case FOURCC('b', 't', 'r', 't'):
+ {
+ *offset += chunk_size;
+
+ uint8_t buffer[12];
+ if (chunk_data_size != sizeof(buffer)) {
+ return ERROR_MALFORMED;
+ }
+
+ if (mDataSource->readAt(
+ data_offset, buffer, chunk_data_size) < chunk_data_size) {
+ return ERROR_IO;
+ }
+
+ uint32_t maxBitrate = U32_AT(&buffer[4]);
+ uint32_t avgBitrate = U32_AT(&buffer[8]);
+ if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
+ mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
+ }
+ if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
+ mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
+ }
+ break;
+ }
+
case FOURCC('a', 'v', 'c', 'C'):
{
*offset += chunk_size;
sp<ABuffer> buffer = new ABuffer(chunk_data_size);
+ if (buffer->data() == NULL) {
+ ALOGE("b/28471206");
+ return NO_MEMORY;
+ }
+
if (mDataSource->readAt(
data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
return ERROR_IO;
@@ -1761,6 +1816,11 @@
{
sp<ABuffer> buffer = new ABuffer(chunk_data_size);
+ if (buffer->data() == NULL) {
+ ALOGE("b/28471206");
+ return NO_MEMORY;
+ }
+
if (mDataSource->readAt(
data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
return ERROR_IO;
@@ -2094,6 +2154,10 @@
return ERROR_MALFORMED;
}
sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1);
+ if (buffer->data() == NULL) {
+ ALOGE("b/28471206");
+ return NO_MEMORY;
+ }
if (mDataSource->readAt(
data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) {
return ERROR_IO;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index db20590..46a32fb 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1929,22 +1929,6 @@
*type = (byte & 0x1F);
}
-static const uint8_t *findNextStartCode(
- const uint8_t *data, size_t length) {
-
- ALOGV("findNextStartCode: %p %zu", data, length);
-
- size_t bytesLeft = length;
- while (bytesLeft > 4 &&
- memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) {
- --bytesLeft;
- }
- if (bytesLeft <= 4) {
- bytesLeft = 0; // Last parameter set
- }
- return &data[length - bytesLeft];
-}
-
const uint8_t *MPEG4Writer::Track::parseParamSet(
const uint8_t *data, size_t length, int type, size_t *paramSetLen) {
@@ -1952,7 +1936,7 @@
CHECK(type == kNalUnitTypeSeqParamSet ||
type == kNalUnitTypePicParamSet);
- const uint8_t *nextStartCode = findNextStartCode(data, length);
+ const uint8_t *nextStartCode = findNextNalStartCode(data, length);
*paramSetLen = nextStartCode - data;
if (*paramSetLen == 0) {
ALOGE("Param set is malformed, since its length is 0");
@@ -2198,10 +2182,7 @@
const uint8_t *nextStartCode = data;
size_t bytesLeft = size;
while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
- nextStartCode = findNextStartCode(tmp + 4, bytesLeft - 4);
- if (nextStartCode == NULL) {
- return ERROR_MALFORMED;
- }
+ nextStartCode = findNextNalStartCode(tmp + 4, bytesLeft - 4);
status_t err = paramSets.addNalUnit(tmp + 4, (nextStartCode - tmp) - 4);
if (err != OK) {
return ERROR_MALFORMED;
@@ -3057,11 +3038,14 @@
mOwner->writeInt8(0x15); // streamType AudioStream
mOwner->writeInt16(0x03); // XXX
- mOwner->writeInt8(0x00); // buffer size 24-bit
- int32_t bitRate;
- bool success = mMeta->findInt32(kKeyBitRate, &bitRate);
- mOwner->writeInt32(success ? bitRate : 96000); // max bit rate
- mOwner->writeInt32(success ? bitRate : 96000); // avg bit rate
+ mOwner->writeInt8(0x00); // buffer size 24-bit (0x300)
+
+ int32_t avgBitrate = 256000;
+ (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
+ int32_t maxBitrate = avgBitrate;
+ (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
+ mOwner->writeInt32(maxBitrate);
+ mOwner->writeInt32(avgBitrate);
mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
mOwner->writeInt8(mCodecSpecificDataSize);
@@ -3095,12 +3079,17 @@
mOwner->writeInt8(0x11); // streamType VisualStream
static const uint8_t kData[] = {
- 0x01, 0x77, 0x00,
- 0x00, 0x03, 0xe8, 0x00,
- 0x00, 0x03, 0xe8, 0x00
+ 0x01, 0x77, 0x00, // buffer size 96000 bytes
};
mOwner->write(kData, sizeof(kData));
+ int32_t avgBitrate = 256000;
+ (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
+ int32_t maxBitrate = avgBitrate;
+ (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
+ mOwner->writeInt32(maxBitrate);
+ mOwner->writeInt32(avgBitrate);
+
mOwner->writeInt8(0x05); // DecoderSpecificInfoTag
mOwner->writeInt8(mCodecSpecificDataSize);
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 271c69b..a669dca 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -232,7 +232,7 @@
}
status_t NuMediaExtractor::getTrackFormat(
- size_t index, sp<AMessage> *format) const {
+ size_t index, sp<AMessage> *format, uint32_t flags) const {
Mutex::Autolock autoLock(mLock);
*format = NULL;
@@ -245,7 +245,7 @@
return -ERANGE;
}
- sp<MetaData> meta = mImpl->getTrackMetaData(index);
+ sp<MetaData> meta = mImpl->getTrackMetaData(index, flags);
// Extractors either support trackID-s or not, so either all tracks have trackIDs or none.
// Generate trackID if missing.
int32_t trackID;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 3e1badf..aa64d22 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -157,9 +157,14 @@
msg->setInt64("durationUs", durationUs);
}
- int avgBitRate;
+ int32_t avgBitRate;
if (meta->findInt32(kKeyBitRate, &avgBitRate)) {
- msg->setInt32("bit-rate", avgBitRate);
+ msg->setInt32("bitrate", avgBitRate);
+ }
+
+ int32_t maxBitRate;
+ if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)) {
+ msg->setInt32("max-bitrate", maxBitRate);
}
int32_t isSync;
@@ -465,6 +470,18 @@
buffer->meta()->setInt32("csd", true);
buffer->meta()->setInt64("timeUs", 0);
msg->setBuffer("csd-0", buffer);
+
+ uint32_t maxBitrate, avgBitrate;
+ if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
+ if (!meta->hasData(kKeyMaxBitRate)
+ && maxBitrate > 0 && maxBitrate <= INT32_MAX) {
+ msg->setInt32("max-bitrate", (int32_t)maxBitrate);
+ }
+ if (!meta->hasData(kKeyBitRate)
+ && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
+ msg->setInt32("bitrate", (int32_t)avgBitrate);
+ }
+ }
} else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
if (buffer.get() == NULL || buffer->base() == NULL) {
@@ -551,12 +568,20 @@
return OK;
}
-static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
+const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
+ uint8_t *res = NULL;
+ if (length > 4) {
+ // minus 1 as to not match NAL start code at end
+ res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
+ }
+ return res != NULL && res < data + length - 4 ? res : &data[length];
+}
+static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
avcc[0] = 1; // version
- avcc[1] = 0x64; // profile
- avcc[2] = 0; // unused (?)
- avcc[3] = 0xd; // level
+ avcc[1] = 0x64; // profile (default to high)
+ avcc[2] = 0; // constraints (default to none)
+ avcc[3] = 0xd; // level (default to 1.3)
avcc[4] = 0xff; // reserved+size
size_t i = 0;
@@ -564,26 +589,28 @@
int lastparamoffset = 0;
int avccidx = 6;
do {
- if (i >= csd0->size() - 4 ||
- memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
- if (i >= csd0->size() - 4) {
- // there can't be another param here, so use all the rest
- i = csd0->size();
+ i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
+ ALOGV("block at %zu, last was %d", i, lastparamoffset);
+ if (lastparamoffset > 0) {
+ const uint8_t *lastparam = csd0->data() + lastparamoffset;
+ int size = i - lastparamoffset;
+ if (size > 3) {
+ if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
+ ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
+ avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
+ } else if (!numparams) {
+ // fill in profile, constraints and level
+ memcpy(avcc + 1, lastparam + 1, 3);
+ }
}
- ALOGV("block at %zu, last was %d", i, lastparamoffset);
- if (lastparamoffset > 0) {
- int size = i - lastparamoffset;
- avcc[avccidx++] = size >> 8;
- avcc[avccidx++] = size & 0xff;
- memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
- avccidx += size;
- numparams++;
- }
- i += 4;
- lastparamoffset = i;
- } else {
- i++;
+ avcc[avccidx++] = size >> 8;
+ avcc[avccidx++] = size & 0xff;
+ memcpy(avcc+avccidx, lastparam, size);
+ avccidx += size;
+ numparams++;
}
+ i += 4;
+ lastparamoffset = i;
} while(i < csd0->size());
ALOGV("csd0 contains %d params", numparams);
@@ -595,26 +622,18 @@
int numpicparamsoffset = avccidx;
avccidx++;
do {
- if (i >= csd1->size() - 4 ||
- memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
- if (i >= csd1->size() - 4) {
- // there can't be another param here, so use all the rest
- i = csd1->size();
- }
- ALOGV("block at %zu, last was %d", i, lastparamoffset);
- if (lastparamoffset > 0) {
- int size = i - lastparamoffset;
- avcc[avccidx++] = size >> 8;
- avcc[avccidx++] = size & 0xff;
- memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
- avccidx += size;
- numparams++;
- }
- i += 4;
- lastparamoffset = i;
- } else {
- i++;
+ i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
+ ALOGV("block at %zu, last was %d", i, lastparamoffset);
+ if (lastparamoffset > 0) {
+ int size = i - lastparamoffset;
+ avcc[avccidx++] = size >> 8;
+ avcc[avccidx++] = size & 0xff;
+ memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
+ avccidx += size;
+ numparams++;
}
+ i += 4;
+ lastparamoffset = i;
} while(i < csd1->size());
avcc[numpicparamsoffset] = numparams;
return avccidx;
@@ -638,15 +657,16 @@
esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
esds[12] = (configdescriptorsize & 0x7f);
esds[13] = 0x40; // objectTypeIndication
- esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
- esds[15] = 0x00; // but the actual values here were taken from a real file.
+ // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
+ esds[14] = 0x15; // streamType(5), upStream(0),
+ esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
esds[16] = 0x18;
esds[17] = 0x00;
- esds[18] = 0x00;
+ esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
esds[19] = 0x00;
esds[20] = 0xfa;
esds[21] = 0x00;
- esds[22] = 0x00;
+ esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
esds[23] = 0x00;
esds[24] = 0xfa;
esds[25] = 0x00;
@@ -657,7 +677,6 @@
esds[30] = (csd0size & 0x7f);
memcpy((void*)&esds[31], csd0->data(), csd0size);
// data following this is ignored, so don't bother appending it
-
}
static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
@@ -1059,7 +1078,7 @@
int32_t brate = -1;
if (!meta->findInt32(kKeyBitRate, &brate)) {
ALOGV("track of type '%s' does not publish bitrate", mime);
- }
+ }
info.bit_rate = brate;
diff --git a/media/libstagefright/codecs/amrwbenc/src/convolve.c b/media/libstagefright/codecs/amrwbenc/src/convolve.c
index 9b8b3aa..8c24414 100644
--- a/media/libstagefright/codecs/amrwbenc/src/convolve.c
+++ b/media/libstagefright/codecs/amrwbenc/src/convolve.c
@@ -47,48 +47,53 @@
s = vo_mult32((*tmpX++), (*tmpH--));i--;
while(i>0)
{
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = voround(L_shl(s, 1));
n++;
tmpH = h+n;
tmpX = x;
i=n+1;
- s = vo_mult32((*tmpX++), (*tmpH--));i--;
- s += vo_mult32((*tmpX++), (*tmpH--));i--;
+ s = vo_mult32((*tmpX++), (*tmpH--));
+ i--;
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ i--;
while(i>0)
{
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = voround(L_shl(s, 1));
n++;
tmpH = h+n;
tmpX = x;
i=n+1;
- s = vo_mult32((*tmpX++), (*tmpH--));i--;
- s += vo_mult32((*tmpX++), (*tmpH--));i--;
- s += vo_mult32((*tmpX++), (*tmpH--));i--;
+ s = vo_mult32((*tmpX++), (*tmpH--));
+ i--;
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ i--;
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ i--;
while(i>0)
{
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = voround(L_shl(s, 1));
n++;
s = 0;
@@ -97,13 +102,13 @@
i=n+1;
while(i>0)
{
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
- s += vo_mult32((*tmpX++), (*tmpH--));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
+ s = L_add(s, vo_mult32((*tmpX++), (*tmpH--)));
i -= 4;
}
- y[n] = ((s<<1) + 0x8000)>>16;
+ y[n] = voround(L_shl(s, 1));
n++;
}
return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
index de2a221..b453b25 100644
--- a/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
+++ b/media/libstagefright/codecs/amrwbenc/src/pitch_f4.c
@@ -84,8 +84,8 @@
/* Find interval to compute normalized correlation */
- t_min = t0_min - L_INTERPOL1;
- t_max = t0_max + L_INTERPOL1;
+ t_min = L_sub(t0_min, L_INTERPOL1);
+ t_max = L_add(t0_max, L_INTERPOL1);
corr = &corr_v[-t_min];
/* Compute normalized correlation between target and filtered excitation */
#ifdef ASM_OPT /* asm optimization branch */
@@ -188,15 +188,15 @@
L_tmp = 0;
for (i = 0; i < 64; i+=4)
{
- L_tmp += (xn[i] * xn[i]);
- L_tmp += (xn[i+1] * xn[i+1]);
- L_tmp += (xn[i+2] * xn[i+2]);
- L_tmp += (xn[i+3] * xn[i+3]);
+ L_tmp = L_add(L_tmp, (xn[i] * xn[i]));
+ L_tmp = L_add(L_tmp, (xn[i+1] * xn[i+1]));
+ L_tmp = L_add(L_tmp, (xn[i+2] * xn[i+2]));
+ L_tmp = L_add(L_tmp, (xn[i+3] * xn[i+3]));
}
- L_tmp = (L_tmp << 1) + 1;
+ L_tmp = L_add(L_shl(L_tmp, 1), 1);
exp = norm_l(L_tmp);
- exp = (32 - exp);
+ exp = L_sub(32, exp);
//exp = exp + 2; /* energy of xn[] x 2 + rounded up */
scale = -(exp >> 1); /* (1<<scale) < 1/sqrt(energy rounded) */
@@ -209,36 +209,36 @@
L_tmp1 = 0;
for (i = 0; i < 64; i+=4)
{
- L_tmp += (xn[i] * excf[i]);
- L_tmp1 += (excf[i] * excf[i]);
- L_tmp += (xn[i+1] * excf[i+1]);
- L_tmp1 += (excf[i+1] * excf[i+1]);
- L_tmp += (xn[i+2] * excf[i+2]);
- L_tmp1 += (excf[i+2] * excf[i+2]);
- L_tmp += (xn[i+3] * excf[i+3]);
- L_tmp1 += (excf[i+3] * excf[i+3]);
+ L_tmp = L_add(L_tmp, (xn[i] * excf[i]));
+ L_tmp1 = L_add(L_tmp1, (excf[i] * excf[i]));
+ L_tmp = L_add(L_tmp, (xn[i+1] * excf[i+1]));
+ L_tmp1 = L_add(L_tmp1, (excf[i+1] * excf[i+1]));
+ L_tmp = L_add(L_tmp, (xn[i+2] * excf[i+2]));
+ L_tmp1 = L_add(L_tmp1, (excf[i+2] * excf[i+2]));
+ L_tmp = L_add(L_tmp, (xn[i+3] * excf[i+3]));
+ L_tmp1 = L_add(L_tmp1, (excf[i+3] * excf[i+3]));
}
- L_tmp = (L_tmp << 1) + 1;
- L_tmp1 = (L_tmp1 << 1) + 1;
+ L_tmp = L_add(L_shl(L_tmp, 1), 1);
+ L_tmp1 = L_add(L_shl(L_tmp1, 1), 1);
exp = norm_l(L_tmp);
- L_tmp = (L_tmp << exp);
- exp_corr = (30 - exp);
+ L_tmp = L_shl(L_tmp, exp);
+ exp_corr = L_sub(30, exp);
corr = extract_h(L_tmp);
exp = norm_l(L_tmp1);
- L_tmp = (L_tmp1 << exp);
- exp_norm = (30 - exp);
+ L_tmp = L_shl(L_tmp1, exp);
+ exp_norm = L_sub(30, exp);
Isqrt_n(&L_tmp, &exp_norm);
norm = extract_h(L_tmp);
/* Normalize correlation = correlation * (1/sqrt(energy)) */
- L_tmp = vo_L_mult(corr, norm);
+ L_tmp = L_mult(corr, norm);
- L_tmp2 = exp_corr + exp_norm + scale;
+ L_tmp2 = L_add(exp_corr, exp_norm + scale);
if(L_tmp2 < 0)
{
L_tmp2 = -L_tmp2;
@@ -246,10 +246,10 @@
}
else
{
- L_tmp = L_tmp << L_tmp2;
+ L_tmp = L_shl(L_tmp, L_tmp2);
}
- corr_norm[t] = vo_round(L_tmp);
+ corr_norm[t] = voround(L_tmp);
/* modify the filtered excitation excf[] for the next iteration */
if(t != t_max)
@@ -310,13 +310,13 @@
ptr = &(inter4_1[k][0]);
L_sum = vo_mult32(x[0], (*ptr++));
- L_sum += vo_mult32(x[1], (*ptr++));
- L_sum += vo_mult32(x[2], (*ptr++));
- L_sum += vo_mult32(x[3], (*ptr++));
- L_sum += vo_mult32(x[4], (*ptr++));
- L_sum += vo_mult32(x[5], (*ptr++));
- L_sum += vo_mult32(x[6], (*ptr++));
- L_sum += vo_mult32(x[7], (*ptr++));
+ L_sum = L_add(L_sum, vo_mult32(x[1], (*ptr++)));
+ L_sum = L_add(L_sum, vo_mult32(x[2], (*ptr++)));
+ L_sum = L_add(L_sum, vo_mult32(x[3], (*ptr++)));
+ L_sum = L_add(L_sum, vo_mult32(x[4], (*ptr++)));
+ L_sum = L_add(L_sum, vo_mult32(x[5], (*ptr++)));
+ L_sum = L_add(L_sum, vo_mult32(x[6], (*ptr++)));
+ L_sum = L_add(L_sum, vo_mult32(x[7], (*ptr++)));
sum = extract_h(L_add(L_shl2(L_sum, 2), 0x8000));
return (sum);
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index d59f129..b908ff8 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -810,10 +810,10 @@
vo_p2 = vo_p0-1;
for (j = 1; j <= M/4; j++)
{
- L_tmp -= *vo_p1++ * *vo_p2--;
- L_tmp -= *vo_p1++ * *vo_p2--;
- L_tmp -= *vo_p1++ * *vo_p2--;
- L_tmp -= *vo_p1++ * *vo_p2--;
+ L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
+ L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
+ L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
+ L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--);
}
*vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4));
}
@@ -1205,7 +1205,7 @@
*------------------------------------------------------*/
/* y2 in Q9, gain_pit in Q14 */
- L_tmp = (gain_code * y2[L_SUBFR - 1])<<1;
+ L_tmp = L_mult(gain_code, y2[L_SUBFR - 1]);
L_tmp = L_shl(L_tmp, (5 + shift));
L_tmp = L_negate(L_tmp);
L_tmp += (xn[L_SUBFR - 1] * 16384)<<1;
@@ -1220,8 +1220,8 @@
{
Word32 tmp;
/* code in Q9, gain_pit in Q14 */
- L_tmp = (gain_code * code[i])<<1;
- L_tmp = (L_tmp << 5);
+ L_tmp = L_mult(gain_code, code[i]);
+ L_tmp = L_shl(L_tmp, 5);
tmp = L_mult(exc[i + i_subfr], gain_pit); // (exc[i + i_subfr] * gain_pit)<<1
L_tmp = L_add(L_tmp, tmp);
L_tmp = L_shl2(L_tmp, 1);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 75998ef..d2fee81 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -579,6 +579,7 @@
IAudioFlinger::track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ pid_t pid,
pid_t tid,
audio_session_t *sessionId,
int clientUid,
@@ -590,6 +591,15 @@
status_t lStatus;
audio_session_t lSessionId;
+ const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ if (pid == -1 || !isTrustedCallingUid(callingUid)) {
+ const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW_IF(pid != -1 && pid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, pid);
+ pid = callingPid;
+ }
+
// client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
// but if someone uses binder directly they could bypass that and cause us to crash
if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
@@ -634,7 +644,6 @@
goto Exit;
}
- pid_t pid = IPCThreadState::self()->getCallingPid();
client = registerPid(pid);
PlaybackThread *effectThread = NULL;
@@ -1455,6 +1464,7 @@
const String16& opPackageName,
size_t *frameCount,
IAudioFlinger::track_flags_t *flags,
+ pid_t pid,
pid_t tid,
int clientUid,
audio_session_t *sessionId,
@@ -1472,11 +1482,21 @@
cblk.clear();
buffers.clear();
+ bool updatePid = (pid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
if (!isTrustedCallingUid(callingUid)) {
ALOGW_IF((uid_t)clientUid != callingUid,
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
clientUid = callingUid;
+ updatePid = true;
+ }
+
+ if (updatePid) {
+ const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW_IF(pid != -1 && pid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, pid);
+ pid = callingPid;
}
// check calling permissions
@@ -1516,7 +1536,6 @@
goto Exit;
}
- pid_t pid = IPCThreadState::self()->getCallingPid();
client = registerPid(pid);
if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 96d38d0..59ad688 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -107,6 +107,7 @@
IAudioFlinger::track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ pid_t pid,
pid_t tid,
audio_session_t *sessionId,
int clientUid,
@@ -120,6 +121,7 @@
const String16& opPackageName,
size_t *pFrameCount,
IAudioFlinger::track_flags_t *flags,
+ pid_t pid,
pid_t tid,
int clientUid,
audio_session_t *sessionId,
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index afc2440..3c73543 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -105,11 +105,10 @@
return true;
}
-bool captureAudioOutputAllowed() {
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
- // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
- bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput);
+ bool ok = checkPermission(sCaptureAudioOutput, pid, uid);
if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
return ok;
}
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index 1e79553..8b1bc00 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -21,7 +21,7 @@
extern pid_t getpid_cached;
bool isTrustedCallingUid(uid_t uid);
bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
-bool captureAudioOutputAllowed();
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
bool captureHotwordAllowed();
bool settingsAllowed();
bool modifyAudioRoutingAllowed();
diff --git a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
index 09a931f..151d066 100644
--- a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
@@ -190,7 +190,8 @@
}
if (((*pDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX)
- && !captureAudioOutputAllowed()) {
+ && !captureAudioOutputAllowed(IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid())) {
ALOGE("open_input() permission denied: capture not allowed");
return AUDIO_IO_HANDLE_NONE;
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 92a1285..02603b8 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -260,6 +260,7 @@
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
@@ -282,11 +283,22 @@
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status;
AudioPolicyInterface::input_type_t inputType;
+
+ bool updatePid = (pid == -1);
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
- ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
+ if (!isTrustedCallingUid(callingUid)) {
+ ALOGW_IF(uid != -1 && uid != (int)callingUid,
"%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
uid = callingUid;
+ updatePid = true;
+ }
+
+ if (updatePid) {
+ const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW_IF(pid != -1 && pid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, pid);
+ pid = callingPid;
}
{
@@ -306,7 +318,7 @@
case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
// FIXME: use the same permission as for remote submix for now.
case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
- if (!captureAudioOutputAllowed()) {
+ if (!captureAudioOutputAllowed(pid, uid)) {
ALOGE("getInputForAttr() permission denied: capture not allowed");
status = PERMISSION_DENIED;
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index c830454..7c9315d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -234,6 +234,7 @@
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid __unused,
uid_t uid __unused,
uint32_t samplingRate,
audio_format_t format,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 2710ac7..0b2cb35 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -99,6 +99,7 @@
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
+ pid_t pid,
uid_t uid,
uint32_t samplingRate,
audio_format_t format,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0e4e244..c0de95a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2967,19 +2967,28 @@
}
void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
- Mutex::Autolock l(mRequestLock);
- // Check all streams needed by repeating requests are still valid. Otherwise, stop
- // repeating requests.
- for (const auto& request : mRepeatingRequests) {
- for (const auto& s : request->mOutputStreams) {
- if (s->isAbandoned()) {
- int64_t lastFrameNumber = 0;
- clearRepeatingRequestsLocked(&lastFrameNumber);
- mListener->notifyRepeatingRequestError(lastFrameNumber);
- return;
+ bool surfaceAbandoned = false;
+ int64_t lastFrameNumber = 0;
+ {
+ Mutex::Autolock l(mRequestLock);
+ // Check all streams needed by repeating requests are still valid. Otherwise, stop
+ // repeating requests.
+ for (const auto& request : mRepeatingRequests) {
+ for (const auto& s : request->mOutputStreams) {
+ if (s->isAbandoned()) {
+ surfaceAbandoned = true;
+ clearRepeatingRequestsLocked(&lastFrameNumber);
+ break;
+ }
+ }
+ if (surfaceAbandoned) {
+ break;
}
}
}
+ if (surfaceAbandoned) {
+ mListener->notifyRepeatingRequestError(lastFrameNumber);
+ }
}
bool Camera3Device::RequestThread::threadLoop() {