Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

frameworks-av: 提交

frameworks/av


Commit MetaInfo

修订版834fa293bf296c85169338c498cdc0bbf9891e2b (tree)
时间2019-10-24 13:07:30
作者Chih-Wei Huang <cwhuang@linu...>
CommiterChih-Wei Huang

Log Message

Android 8.1.0 Release 69 (5794017)
-----BEGIN PGP SIGNATURE-----

iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCXZfQawAKCRDorT+BmrEO
eByZAJ40ShdvBhsIg/E2eo7t1VWuYjaOMACfVbkJCnQUx7u68pDsl6TiTpgQNYE=
=UuTD
-----END PGP SIGNATURE-----

Merge tag 'android-8.1.0_r69' into oreo-x86

Android 8.1.0 Release 69 (5794017)

更改概述

差异

--- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp
@@ -314,6 +314,11 @@ bool NuPlayer::CCDecoder::extractFromMPEGUserData(const sp<ABuffer> &accessUnit)
314314 const size_t *userData = (size_t *)mpegUserData->data();
315315
316316 for (size_t i = 0; i < mpegUserData->size() / sizeof(size_t); ++i) {
317+ if (accessUnit->size() < userData[i]) {
318+ ALOGW("b/129068792, skip invalid offset for user data");
319+ android_errorWriteLog(0x534e4554, "129068792");
320+ continue;
321+ }
317322 trackAdded |= parseMPEGUserDataUnit(
318323 timeUs, accessUnit->data() + userData[i], accessUnit->size() - userData[i]);
319324 }
@@ -323,6 +328,12 @@ bool NuPlayer::CCDecoder::extractFromMPEGUserData(const sp<ABuffer> &accessUnit)
323328
324329 // returns true if a new CC track is found
325330 bool NuPlayer::CCDecoder::parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size) {
331+ if (size < 9) {
332+ ALOGW("b/129068792, MPEG user data size too small %zu", size);
333+ android_errorWriteLog(0x534e4554, "129068792");
334+ return false;
335+ }
336+
326337 ABitReader br(data + 4, 5);
327338
328339 uint32_t user_identifier = br.getBits(32);
@@ -375,8 +386,14 @@ bool NuPlayer::CCDecoder::parseMPEGCCData(int64_t timeUs, const uint8_t *data, s
375386 mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
376387 br.skipBits(16);
377388 } else if (mDTVCCPacket->size() > 0 && cc_type == 2) {
378- memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
379- mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
389+ if (mDTVCCPacket->capacity() - mDTVCCPacket->size() >= 2) {
390+ memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
391+ mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
392+ } else {
393+ ALOGW("b/129068792, skip CC due to too much data(%zu, %zu)",
394+ mDTVCCPacket->capacity(), mDTVCCPacket->size());
395+ android_errorWriteLog(0x534e4554, "129068792");
396+ }
380397 br.skipBits(16);
381398 } else if (cc_type == 0 || cc_type == 1) {
382399 uint8_t cc_data_1 = br.getBits(8) & 0x7f;
@@ -463,6 +480,11 @@ bool NuPlayer::CCDecoder::parseDTVCCPacket(int64_t timeUs, const uint8_t *data,
463480 size_t trackIndex = getTrackIndex(kTrackTypeCEA708, service_number, &trackAdded);
464481 if (mSelectedTrack == (ssize_t)trackIndex) {
465482 sp<ABuffer> ccPacket = new ABuffer(block_size);
483+ if (ccPacket->capacity() == 0) {
484+ ALOGW("b/129068792, no memory available, %zu", block_size);
485+ android_errorWriteLog(0x534e4554, "129068792");
486+ return false;
487+ }
466488 memcpy(ccPacket->data(), br.data(), block_size);
467489 mCCMap.add(timeUs, ccPacket);
468490 }
--- a/media/libstagefright/AVIExtractor.cpp
+++ /dev/null
@@ -1,1307 +0,0 @@
1-/*
2- * Copyright (C) 2011 The Android Open Source Project
3- *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
6- * You may obtain a copy of the License at
7- *
8- * http://www.apache.org/licenses/LICENSE-2.0
9- *
10- * Unless required by applicable law or agreed to in writing, software
11- * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13- * See the License for the specific language governing permissions and
14- * limitations under the License.
15- */
16-
17-//#define LOG_NDEBUG 0
18-#define LOG_TAG "AVIExtractor"
19-#include <utils/Log.h>
20-
21-#include "include/avc_utils.h"
22-#include "include/AVIExtractor.h"
23-
24-#include <binder/ProcessState.h>
25-#include <media/stagefright/foundation/hexdump.h>
26-#include <media/stagefright/foundation/ABuffer.h>
27-#include <media/stagefright/foundation/ADebug.h>
28-#include <media/stagefright/DataSource.h>
29-#include <media/stagefright/MediaBuffer.h>
30-#include <media/stagefright/MediaBufferGroup.h>
31-#include <media/stagefright/MediaDefs.h>
32-#include <media/stagefright/MediaErrors.h>
33-#include <media/stagefright/MetaData.h>
34-#include <media/stagefright/Utils.h>
35-
36-namespace android {
37-
38-struct AVIExtractor::AVISource : public MediaSource {
39- AVISource(const sp<AVIExtractor> &extractor, size_t trackIndex);
40-
41- virtual status_t start(MetaData *params);
42- virtual status_t stop();
43-
44- virtual sp<MetaData> getFormat();
45-
46- virtual status_t read(
47- MediaBuffer **buffer, const ReadOptions *options);
48-
49-protected:
50- virtual ~AVISource();
51-
52-private:
53- sp<AVIExtractor> mExtractor;
54- size_t mTrackIndex;
55- const AVIExtractor::Track &mTrack;
56- MediaBufferGroup *mBufferGroup;
57- size_t mSampleIndex;
58-
59- sp<MP3Splitter> mSplitter;
60-
61- DISALLOW_EVIL_CONSTRUCTORS(AVISource);
62-};
63-
64-////////////////////////////////////////////////////////////////////////////////
65-
66-struct AVIExtractor::MP3Splitter : public RefBase {
67- MP3Splitter();
68-
69- void clear();
70- void append(MediaBuffer *buffer);
71- status_t read(MediaBuffer **buffer);
72-
73-protected:
74- virtual ~MP3Splitter();
75-
76-private:
77- bool mFindSync;
78- int64_t mBaseTimeUs;
79- int64_t mNumSamplesRead;
80- sp<ABuffer> mBuffer;
81-
82- bool resync();
83-
84- DISALLOW_EVIL_CONSTRUCTORS(MP3Splitter);
85-};
86-
87-////////////////////////////////////////////////////////////////////////////////
88-
89-AVIExtractor::AVISource::AVISource(
90- const sp<AVIExtractor> &extractor, size_t trackIndex)
91- : mExtractor(extractor),
92- mTrackIndex(trackIndex),
93- mTrack(mExtractor->mTracks.itemAt(trackIndex)),
94- mBufferGroup(NULL) {
95-}
96-
97-AVIExtractor::AVISource::~AVISource() {
98- if (mBufferGroup) {
99- stop();
100- }
101-}
102-
103-status_t AVIExtractor::AVISource::start(MetaData *params) {
104- CHECK(!mBufferGroup);
105-
106- mBufferGroup = new MediaBufferGroup;
107-
108- mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
109- mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
110- mSampleIndex = 0;
111-
112- const char *mime;
113- CHECK(mTrack.mMeta->findCString(kKeyMIMEType, &mime));
114-
115- if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
116- mSplitter = new MP3Splitter;
117- } else {
118- mSplitter.clear();
119- }
120-
121- return OK;
122-}
123-
124-status_t AVIExtractor::AVISource::stop() {
125- CHECK(mBufferGroup);
126-
127- delete mBufferGroup;
128- mBufferGroup = NULL;
129-
130- mSplitter.clear();
131-
132- return OK;
133-}
134-
135-sp<MetaData> AVIExtractor::AVISource::getFormat() {
136- return mTrack.mMeta;
137-}
138-
139-status_t AVIExtractor::AVISource::read(
140- MediaBuffer **buffer, const ReadOptions *options) {
141- CHECK(mBufferGroup);
142-
143- *buffer = NULL;
144-
145- int64_t seekTimeUs;
146- ReadOptions::SeekMode seekMode;
147- if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
148- status_t err =
149- mExtractor->getSampleIndexAtTime(
150- mTrackIndex, seekTimeUs, seekMode, &mSampleIndex);
151-
152- if (err != OK) {
153- return ERROR_END_OF_STREAM;
154- }
155-
156- if (mSplitter != NULL) {
157- mSplitter->clear();
158- }
159- }
160-
161- for (;;) {
162- if (mSplitter != NULL) {
163- status_t err = mSplitter->read(buffer);
164-
165- if (err == OK) {
166- break;
167- } else if (err != -EAGAIN) {
168- return err;
169- }
170- }
171-
172- off64_t offset;
173- size_t size;
174- bool isKey;
175- int64_t timeUs;
176- status_t err = mExtractor->getSampleInfo(
177- mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);
178-
179- ++mSampleIndex;
180-
181- if (err != OK) {
182- return ERROR_END_OF_STREAM;
183- }
184-
185- MediaBuffer *out;
186- CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK);
187-
188- ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size);
189-
190- if (n < (ssize_t)size) {
191- return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
192- }
193-
194- out->set_range(0, size);
195-
196- out->meta_data()->setInt64(kKeyTime, timeUs);
197-
198- if (isKey) {
199- out->meta_data()->setInt32(kKeyIsSyncFrame, 1);
200- }
201-
202- if (mSplitter == NULL) {
203- *buffer = out;
204- break;
205- }
206-
207- mSplitter->append(out);
208- out->release();
209- out = NULL;
210- }
211-
212- return OK;
213-}
214-
215-////////////////////////////////////////////////////////////////////////////////
216-
217-AVIExtractor::MP3Splitter::MP3Splitter()
218- : mFindSync(true),
219- mBaseTimeUs(-1ll),
220- mNumSamplesRead(0) {
221-}
222-
223-AVIExtractor::MP3Splitter::~MP3Splitter() {
224-}
225-
226-void AVIExtractor::MP3Splitter::clear() {
227- mFindSync = true;
228- mBaseTimeUs = -1ll;
229- mNumSamplesRead = 0;
230-
231- if (mBuffer != NULL) {
232- mBuffer->setRange(0, 0);
233- }
234-}
235-
236-void AVIExtractor::MP3Splitter::append(MediaBuffer *buffer) {
237- size_t prevCapacity = (mBuffer != NULL) ? mBuffer->capacity() : 0;
238-
239- if (mBaseTimeUs < 0) {
240- CHECK(mBuffer == NULL || mBuffer->size() == 0);
241- CHECK(buffer->meta_data()->findInt64(kKeyTime, &mBaseTimeUs));
242- mNumSamplesRead = 0;
243- }
244-
245- if (mBuffer != NULL && mBuffer->offset() > 0) {
246- memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
247- mBuffer->setRange(0, mBuffer->size());
248- }
249-
250- if (mBuffer == NULL
251- || mBuffer->size() + buffer->range_length() > prevCapacity) {
252- size_t newCapacity =
253- (prevCapacity + buffer->range_length() + 1023) & ~1023;
254-
255- sp<ABuffer> newBuffer = new ABuffer(newCapacity);
256- if (mBuffer != NULL) {
257- memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
258- newBuffer->setRange(0, mBuffer->size());
259- } else {
260- newBuffer->setRange(0, 0);
261- }
262- mBuffer = newBuffer;
263- }
264-
265- memcpy(mBuffer->data() + mBuffer->size(),
266- (const uint8_t *)buffer->data() + buffer->range_offset(),
267- buffer->range_length());
268-
269- mBuffer->setRange(0, mBuffer->size() + buffer->range_length());
270-}
271-
272-bool AVIExtractor::MP3Splitter::resync() {
273- if (mBuffer == NULL) {
274- return false;
275- }
276-
277- bool foundSync = false;
278- for (size_t offset = 0; offset + 3 < mBuffer->size(); ++offset) {
279- uint32_t firstHeader = U32_AT(mBuffer->data() + offset);
280-
281- size_t frameSize;
282- if (!GetMPEGAudioFrameSize(firstHeader, &frameSize)) {
283- continue;
284- }
285-
286- size_t subsequentOffset = offset + frameSize;
287- size_t i = 3;
288- while (i > 0) {
289- if (subsequentOffset + 3 >= mBuffer->size()) {
290- break;
291- }
292-
293- static const uint32_t kMask = 0xfffe0c00;
294-
295- uint32_t header = U32_AT(mBuffer->data() + subsequentOffset);
296- if ((header & kMask) != (firstHeader & kMask)) {
297- break;
298- }
299-
300- if (!GetMPEGAudioFrameSize(header, &frameSize)) {
301- break;
302- }
303-
304- subsequentOffset += frameSize;
305- --i;
306- }
307-
308- if (i == 0) {
309- foundSync = true;
310- memmove(mBuffer->data(),
311- mBuffer->data() + offset,
312- mBuffer->size() - offset);
313-
314- mBuffer->setRange(0, mBuffer->size() - offset);
315- break;
316- }
317- }
318-
319- return foundSync;
320-}
321-
322-status_t AVIExtractor::MP3Splitter::read(MediaBuffer **out) {
323- *out = NULL;
324-
325- if (mFindSync) {
326- if (!resync()) {
327- return -EAGAIN;
328- }
329-
330- mFindSync = false;
331- }
332-
333- if (mBuffer->size() < 4) {
334- return -EAGAIN;
335- }
336-
337- uint32_t header = U32_AT(mBuffer->data());
338- size_t frameSize;
339- int sampleRate;
340- int numSamples;
341- if (!GetMPEGAudioFrameSize(
342- header, &frameSize, &sampleRate, NULL, NULL, &numSamples)) {
343- return ERROR_MALFORMED;
344- }
345-
346- if (mBuffer->size() < frameSize) {
347- return -EAGAIN;
348- }
349-
350- MediaBuffer *mbuf = new MediaBuffer(frameSize);
351- memcpy(mbuf->data(), mBuffer->data(), frameSize);
352-
353- int64_t timeUs = mBaseTimeUs + (mNumSamplesRead * 1000000ll) / sampleRate;
354- mNumSamplesRead += numSamples;
355-
356- mbuf->meta_data()->setInt64(kKeyTime, timeUs);
357-
358- mBuffer->setRange(
359- mBuffer->offset() + frameSize, mBuffer->size() - frameSize);
360-
361- *out = mbuf;
362-
363- return OK;
364-}
365-
366-////////////////////////////////////////////////////////////////////////////////
367-
368-AVIExtractor::AVIExtractor(const sp<DataSource> &dataSource)
369- : mDataSource(dataSource) {
370- mInitCheck = parseHeaders();
371-
372- if (mInitCheck != OK) {
373- mTracks.clear();
374- }
375-}
376-
377-AVIExtractor::~AVIExtractor() {
378-}
379-
380-size_t AVIExtractor::countTracks() {
381- return mTracks.size();
382-}
383-
384-sp<MediaSource> AVIExtractor::getTrack(size_t index) {
385- return index < mTracks.size() ? new AVISource(this, index) : NULL;
386-}
387-
388-sp<MetaData> AVIExtractor::getTrackMetaData(
389- size_t index, uint32_t flags) {
390- return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL;
391-}
392-
393-sp<MetaData> AVIExtractor::getMetaData() {
394- sp<MetaData> meta = new MetaData;
395-
396- if (mInitCheck == OK) {
397- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI);
398- }
399-
400- return meta;
401-}
402-
403-status_t AVIExtractor::parseHeaders() {
404- mTracks.clear();
405- mMovieOffset = 0;
406- mFoundIndex = false;
407- mOffsetsAreAbsolute = false;
408-
409- ssize_t res = parseChunk(0ll, -1ll);
410-
411- if (res < 0) {
412- return (status_t)res;
413- }
414-
415- if (mMovieOffset == 0ll || !mFoundIndex) {
416- return ERROR_MALFORMED;
417- }
418-
419- return OK;
420-}
421-
422-ssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) {
423- if (size >= 0 && size < 8) {
424- return ERROR_MALFORMED;
425- }
426-
427- uint8_t tmp[12];
428- ssize_t n = mDataSource->readAt(offset, tmp, 8);
429-
430- if (n < 8) {
431- return (n < 0) ? n : (ssize_t)ERROR_MALFORMED;
432- }
433-
434- uint32_t fourcc = U32_AT(tmp);
435- uint32_t chunkSize = U32LE_AT(&tmp[4]);
436-
437- if (size >= 0 && chunkSize + 8 > size) {
438- return ERROR_MALFORMED;
439- }
440-
441- static const char kPrefix[] = " ";
442- const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth];
443-
444- if (fourcc == FOURCC('L', 'I', 'S', 'T')
445- || fourcc == FOURCC('R', 'I', 'F', 'F')) {
446- // It's a list of chunks
447-
448- if (size >= 0 && size < 12) {
449- return ERROR_MALFORMED;
450- }
451-
452- n = mDataSource->readAt(offset + 8, &tmp[8], 4);
453-
454- if (n < 4) {
455- return (n < 0) ? n : (ssize_t)ERROR_MALFORMED;
456- }
457-
458- uint32_t subFourcc = U32_AT(&tmp[8]);
459-
460- ALOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d",
461- prefix,
462- offset,
463- (char)(subFourcc >> 24),
464- (char)((subFourcc >> 16) & 0xff),
465- (char)((subFourcc >> 8) & 0xff),
466- (char)(subFourcc & 0xff),
467- chunkSize - 4);
468-
469- if (subFourcc == FOURCC('m', 'o', 'v', 'i')) {
470- // We're not going to parse this, but will take note of the
471- // offset.
472-
473- mMovieOffset = offset;
474- } else {
475- off64_t subOffset = offset + 12;
476- off64_t subOffsetLimit = subOffset + chunkSize - 4;
477- while (subOffset < subOffsetLimit) {
478- ssize_t res =
479- parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1);
480-
481- if (res < 0) {
482- return res;
483- }
484-
485- subOffset += res;
486- }
487- }
488- } else {
489- ALOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'",
490- prefix,
491- offset,
492- (char)(fourcc >> 24),
493- (char)((fourcc >> 16) & 0xff),
494- (char)((fourcc >> 8) & 0xff),
495- (char)(fourcc & 0xff));
496-
497- status_t err = OK;
498-
499- switch (fourcc) {
500- case FOURCC('s', 't', 'r', 'h'):
501- {
502- err = parseStreamHeader(offset + 8, chunkSize);
503- break;
504- }
505-
506- case FOURCC('s', 't', 'r', 'f'):
507- {
508- err = parseStreamFormat(offset + 8, chunkSize);
509- break;
510- }
511-
512- case FOURCC('i', 'd', 'x', '1'):
513- {
514- err = parseIndex(offset + 8, chunkSize);
515- break;
516- }
517-
518- default:
519- break;
520- }
521-
522- if (err != OK) {
523- return err;
524- }
525- }
526-
527- if (chunkSize & 1) {
528- ++chunkSize;
529- }
530-
531- return chunkSize + 8;
532-}
533-
534-static const char *GetMIMETypeForHandler(uint32_t handler) {
535- switch (handler) {
536- // Wow... shamelessly copied from
537- // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4
538-
539- case FOURCC('3', 'I', 'V', '2'):
540- case FOURCC('3', 'i', 'v', '2'):
541- case FOURCC('B', 'L', 'Z', '0'):
542- case FOURCC('D', 'I', 'G', 'I'):
543- case FOURCC('D', 'I', 'V', '1'):
544- case FOURCC('d', 'i', 'v', '1'):
545- case FOURCC('D', 'I', 'V', 'X'):
546- case FOURCC('d', 'i', 'v', 'x'):
547- case FOURCC('D', 'X', '5', '0'):
548- case FOURCC('d', 'x', '5', '0'):
549- case FOURCC('D', 'X', 'G', 'M'):
550- case FOURCC('E', 'M', '4', 'A'):
551- case FOURCC('E', 'P', 'H', 'V'):
552- case FOURCC('F', 'M', 'P', '4'):
553- case FOURCC('f', 'm', 'p', '4'):
554- case FOURCC('F', 'V', 'F', 'W'):
555- case FOURCC('H', 'D', 'X', '4'):
556- case FOURCC('h', 'd', 'x', '4'):
557- case FOURCC('M', '4', 'C', 'C'):
558- case FOURCC('M', '4', 'S', '2'):
559- case FOURCC('m', '4', 's', '2'):
560- case FOURCC('M', 'P', '4', 'S'):
561- case FOURCC('m', 'p', '4', 's'):
562- case FOURCC('M', 'P', '4', 'V'):
563- case FOURCC('m', 'p', '4', 'v'):
564- case FOURCC('M', 'V', 'X', 'M'):
565- case FOURCC('R', 'M', 'P', '4'):
566- case FOURCC('S', 'E', 'D', 'G'):
567- case FOURCC('S', 'M', 'P', '4'):
568- case FOURCC('U', 'M', 'P', '4'):
569- case FOURCC('W', 'V', '1', 'F'):
570- case FOURCC('X', 'V', 'I', 'D'):
571- case FOURCC('X', 'v', 'i', 'D'):
572- case FOURCC('x', 'v', 'i', 'd'):
573- case FOURCC('X', 'V', 'I', 'X'):
574- return MEDIA_MIMETYPE_VIDEO_MPEG4;
575-
576- // from http://wiki.multimedia.cx/index.php?title=H264
577- case FOURCC('a', 'v', 'c', '1'):
578- case FOURCC('d', 'a', 'v', 'c'):
579- case FOURCC('x', '2', '6', '4'):
580- case FOURCC('H', '2', '6', '4'):
581- case FOURCC('v', 's', 's', 'h'):
582- return MEDIA_MIMETYPE_VIDEO_AVC;
583-
584- default:
585- return NULL;
586- }
587-}
588-
589-status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
590- if (size != 56) {
591- return ERROR_MALFORMED;
592- }
593-
594- if (mTracks.size() > 99) {
595- return -ERANGE;
596- }
597-
598- sp<ABuffer> buffer = new ABuffer(size);
599- ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
600-
601- if (n < (ssize_t)size) {
602- return n < 0 ? (status_t)n : ERROR_MALFORMED;
603- }
604-
605- const uint8_t *data = buffer->data();
606-
607- uint32_t type = U32_AT(data);
608- uint32_t handler = U32_AT(&data[4]);
609- uint32_t flags = U32LE_AT(&data[8]);
610-
611- sp<MetaData> meta = new MetaData;
612-
613- uint32_t rate = U32LE_AT(&data[20]);
614- uint32_t scale = U32LE_AT(&data[24]);
615-
616- uint32_t sampleSize = U32LE_AT(&data[44]);
617-
618- const char *mime = NULL;
619- Track::Kind kind = Track::OTHER;
620-
621- if (type == FOURCC('v', 'i', 'd', 's')) {
622- mime = GetMIMETypeForHandler(handler);
623-
624- if (mime && strncasecmp(mime, "video/", 6)) {
625- return ERROR_MALFORMED;
626- }
627-
628- if (mime == NULL) {
629- ALOGW("Unsupported video format '%c%c%c%c'",
630- (char)(handler >> 24),
631- (char)((handler >> 16) & 0xff),
632- (char)((handler >> 8) & 0xff),
633- (char)(handler & 0xff));
634- }
635-
636- kind = Track::VIDEO;
637- } else if (type == FOURCC('a', 'u', 'd', 's')) {
638- if (mime && strncasecmp(mime, "audio/", 6)) {
639- return ERROR_MALFORMED;
640- }
641-
642- kind = Track::AUDIO;
643- }
644-
645- if (!mime) {
646- mime = "application/octet-stream";
647- }
648-
649- meta->setCString(kKeyMIMEType, mime);
650-
651- mTracks.push();
652- Track *track = &mTracks.editItemAt(mTracks.size() - 1);
653-
654- track->mMeta = meta;
655- track->mRate = rate;
656- track->mScale = scale;
657- track->mBytesPerSample = sampleSize;
658- track->mKind = kind;
659- track->mNumSyncSamples = 0;
660- track->mThumbnailSampleSize = 0;
661- track->mThumbnailSampleIndex = -1;
662- track->mMaxSampleSize = 0;
663- track->mAvgChunkSize = 1.0;
664- track->mFirstChunkSize = 0;
665-
666- return OK;
667-}
668-
669-status_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) {
670- if (mTracks.isEmpty()) {
671- return ERROR_MALFORMED;
672- }
673-
674- Track *track = &mTracks.editItemAt(mTracks.size() - 1);
675-
676- if (track->mKind == Track::OTHER) {
677- // We don't support this content, but that's not a parsing error.
678- return OK;
679- }
680-
681- bool isVideo = (track->mKind == Track::VIDEO);
682-
683- if ((isVideo && size < 40) || (!isVideo && size < 16)) {
684- // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively.
685- return ERROR_MALFORMED;
686- }
687-
688- sp<ABuffer> buffer = new ABuffer(size);
689- ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
690-
691- if (n < (ssize_t)size) {
692- return n < 0 ? (status_t)n : ERROR_MALFORMED;
693- }
694-
695- const uint8_t *data = buffer->data();
696-
697- if (isVideo) {
698- uint32_t width = U32LE_AT(&data[4]);
699- uint32_t height = U32LE_AT(&data[8]);
700-
701- track->mMeta->setInt32(kKeyWidth, width);
702- track->mMeta->setInt32(kKeyHeight, height);
703- } else {
704- uint32_t format = U16LE_AT(data);
705-
706- if (format == 0x55) {
707- track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
708- } else {
709- ALOGW("Unsupported audio format = 0x%04x", format);
710- }
711-
712- uint32_t numChannels = U16LE_AT(&data[2]);
713- uint32_t sampleRate = U32LE_AT(&data[4]);
714-
715- track->mMeta->setInt32(kKeyChannelCount, numChannels);
716- track->mMeta->setInt32(kKeySampleRate, sampleRate);
717- }
718-
719- return OK;
720-}
721-
722-// static
723-bool AVIExtractor::IsCorrectChunkType(
724- ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) {
725- uint32_t chunkBase = chunkType & 0xffff;
726-
727- switch (kind) {
728- case Track::VIDEO:
729- {
730- if (chunkBase != FOURCC(0, 0, 'd', 'c')
731- && chunkBase != FOURCC(0, 0, 'd', 'b')) {
732- return false;
733- }
734- break;
735- }
736-
737- case Track::AUDIO:
738- {
739- if (chunkBase != FOURCC(0, 0, 'w', 'b')) {
740- return false;
741- }
742- break;
743- }
744-
745- default:
746- break;
747- }
748-
749- if (trackIndex < 0) {
750- return true;
751- }
752-
753- uint8_t hi = chunkType >> 24;
754- uint8_t lo = (chunkType >> 16) & 0xff;
755-
756- if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
757- return false;
758- }
759-
760- if (trackIndex != (10 * (hi - '0') + (lo - '0'))) {
761- return false;
762- }
763-
764- return true;
765-}
766-
767-status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
768- if ((size % 16) != 0) {
769- return ERROR_MALFORMED;
770- }
771-
772- sp<ABuffer> buffer = new ABuffer(size);
773- ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
774-
775- if (n < (ssize_t)size) {
776- return n < 0 ? (status_t)n : ERROR_MALFORMED;
777- }
778-
779- const uint8_t *data = buffer->data();
780-
781- while (size > 0) {
782- uint32_t chunkType = U32_AT(data);
783-
784- uint8_t hi = chunkType >> 24;
785- uint8_t lo = (chunkType >> 16) & 0xff;
786-
787- if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
788- return ERROR_MALFORMED;
789- }
790-
791- size_t trackIndex = 10 * (hi - '0') + (lo - '0');
792-
793- if (trackIndex >= mTracks.size()) {
794- return ERROR_MALFORMED;
795- }
796-
797- Track *track = &mTracks.editItemAt(trackIndex);
798-
799- if (!IsCorrectChunkType(-1, track->mKind, chunkType)) {
800- return ERROR_MALFORMED;
801- }
802-
803- if (track->mKind == Track::OTHER) {
804- data += 16;
805- size -= 16;
806- continue;
807- }
808-
809- uint32_t flags = U32LE_AT(&data[4]);
810- uint32_t offset = U32LE_AT(&data[8]);
811- uint32_t chunkSize = U32LE_AT(&data[12]);
812-
813- if (chunkSize > track->mMaxSampleSize) {
814- track->mMaxSampleSize = chunkSize;
815- }
816-
817- track->mSamples.push();
818-
819- SampleInfo *info =
820- &track->mSamples.editItemAt(track->mSamples.size() - 1);
821-
822- info->mOffset = offset;
823- info->mIsKey = (flags & 0x10) != 0;
824-
825- if (info->mIsKey) {
826- static const size_t kMaxNumSyncSamplesToScan = 20;
827-
828- if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) {
829- if (chunkSize > track->mThumbnailSampleSize) {
830- track->mThumbnailSampleSize = chunkSize;
831-
832- track->mThumbnailSampleIndex =
833- track->mSamples.size() - 1;
834- }
835- }
836-
837- ++track->mNumSyncSamples;
838- }
839-
840- data += 16;
841- size -= 16;
842- }
843-
844- if (!mTracks.isEmpty()) {
845- off64_t offset;
846- size_t size;
847- bool isKey;
848- int64_t timeUs;
849- status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
850-
851- if (err != OK) {
852- mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
853- err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
854-
855- if (err != OK) {
856- return err;
857- }
858- }
859-
860- ALOGV("Chunk offsets are %s",
861- mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative");
862- }
863-
864- for (size_t i = 0; i < mTracks.size(); ++i) {
865- Track *track = &mTracks.editItemAt(i);
866-
867- if (track->mBytesPerSample > 0) {
868- // Assume all chunks are roughly the same size for now.
869-
870- // Compute the avg. size of the first 128 chunks (if there are
871- // that many), but exclude the size of the first one, since
872- // it may be an outlier.
873- size_t numSamplesToAverage = track->mSamples.size();
874- if (numSamplesToAverage > 256) {
875- numSamplesToAverage = 256;
876- }
877-
878- double avgChunkSize = 0;
879- size_t j;
880- for (j = 0; j <= numSamplesToAverage; ++j) {
881- off64_t offset;
882- size_t size;
883- bool isKey;
884- int64_t dummy;
885-
886- status_t err =
887- getSampleInfo(
888- i, j,
889- &offset, &size, &isKey, &dummy);
890-
891- if (err != OK) {
892- return err;
893- }
894-
895- if (j == 0) {
896- track->mFirstChunkSize = size;
897- continue;
898- }
899-
900- avgChunkSize += size;
901- }
902-
903- avgChunkSize /= numSamplesToAverage;
904-
905- track->mAvgChunkSize = avgChunkSize;
906- }
907-
908- int64_t durationUs;
909- CHECK_EQ((status_t)OK,
910- getSampleTime(i, track->mSamples.size() - 1, &durationUs));
911-
912- ALOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
913-
914- track->mMeta->setInt64(kKeyDuration, durationUs);
915- track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize);
916-
917- const char *tmp;
918- CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp));
919-
920- AString mime = tmp;
921-
922- if (!strncasecmp("video/", mime.c_str(), 6)) {
923- if (track->mThumbnailSampleIndex >= 0) {
924- int64_t thumbnailTimeUs;
925- CHECK_EQ((status_t)OK,
926- getSampleTime(i, track->mThumbnailSampleIndex,
927- &thumbnailTimeUs));
928-
929- track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
930- }
931-
932- status_t err = OK;
933-
934- if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
935- err = addMPEG4CodecSpecificData(i);
936- } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
937- err = addH264CodecSpecificData(i);
938- }
939-
940- if (err != OK) {
941- return err;
942- }
943- }
944- }
945-
946- mFoundIndex = true;
947-
948- return OK;
949-}
950-
951-static size_t GetSizeWidth(size_t x) {
952- size_t n = 1;
953- while (x > 127) {
954- ++n;
955- x >>= 7;
956- }
957- return n;
958-}
959-
960-static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
961- while (x > 127) {
962- *dst++ = (x & 0x7f) | 0x80;
963- x >>= 7;
964- }
965- *dst++ = x;
966- return dst;
967-}
968-
969-sp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) {
970- size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
971- size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
972- size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
973-
974- sp<ABuffer> csd = new ABuffer(len3);
975- uint8_t *dst = csd->data();
976- *dst++ = 0x03;
977- dst = EncodeSize(dst, len2 + 3);
978- *dst++ = 0x00; // ES_ID
979- *dst++ = 0x00;
980- *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
981-
982- *dst++ = 0x04;
983- dst = EncodeSize(dst, len1 + 13);
984- *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile
985- for (size_t i = 0; i < 12; ++i) {
986- *dst++ = 0x00;
987- }
988-
989- *dst++ = 0x05;
990- dst = EncodeSize(dst, config->size());
991- memcpy(dst, config->data(), config->size());
992- dst += config->size();
993-
994- // hexdump(csd->data(), csd->size());
995-
996- return csd;
997-}
998-
999-status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
1000- Track *track = &mTracks.editItemAt(trackIndex);
1001-
1002- off64_t offset;
1003- size_t size;
1004- bool isKey;
1005- int64_t timeUs;
1006- status_t err =
1007- getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs);
1008-
1009- if (err != OK) {
1010- return err;
1011- }
1012-
1013- sp<ABuffer> buffer = new ABuffer(size);
1014- ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
1015-
1016- if (n < (ssize_t)size) {
1017- return n < 0 ? (status_t)n : ERROR_MALFORMED;
1018- }
1019-
1020- // Extract everything up to the first VOP start code from the first
1021- // frame's encoded data and use it to construct an ESDS with the
1022- // codec specific data.
1023-
1024- size_t i = 0;
1025- bool found = false;
1026- while (i + 3 < buffer->size()) {
1027- if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) {
1028- found = true;
1029- break;
1030- }
1031-
1032- ++i;
1033- }
1034-
1035- if (!found) {
1036- return ERROR_MALFORMED;
1037- }
1038-
1039- buffer->setRange(0, i);
1040-
1041- sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer);
1042- track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size());
1043-
1044- return OK;
1045-}
1046-
1047-status_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) {
1048- Track *track = &mTracks.editItemAt(trackIndex);
1049-
1050- off64_t offset;
1051- size_t size;
1052- bool isKey;
1053- int64_t timeUs;
1054-
1055- // Extract codec specific data from the first non-empty sample.
1056-
1057- size_t sampleIndex = 0;
1058- for (;;) {
1059- status_t err =
1060- getSampleInfo(
1061- trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs);
1062-
1063- if (err != OK) {
1064- return err;
1065- }
1066-
1067- if (size > 0) {
1068- break;
1069- }
1070-
1071- ++sampleIndex;
1072- }
1073-
1074- sp<ABuffer> buffer = new ABuffer(size);
1075- ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
1076-
1077- if (n < (ssize_t)size) {
1078- return n < 0 ? (status_t)n : ERROR_MALFORMED;
1079- }
1080-
1081- sp<MetaData> meta = MakeAVCCodecSpecificData(buffer);
1082-
1083- if (meta == NULL) {
1084- ALOGE("Unable to extract AVC codec specific data");
1085- return ERROR_MALFORMED;
1086- }
1087-
1088- int32_t width, height;
1089- CHECK(meta->findInt32(kKeyWidth, &width));
1090- CHECK(meta->findInt32(kKeyHeight, &height));
1091-
1092- uint32_t type;
1093- const void *csd;
1094- size_t csdSize;
1095- CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize));
1096-
1097- track->mMeta->setInt32(kKeyWidth, width);
1098- track->mMeta->setInt32(kKeyHeight, height);
1099- track->mMeta->setData(kKeyAVCC, type, csd, csdSize);
1100-
1101- return OK;
1102-}
1103-
1104-status_t AVIExtractor::getSampleInfo(
1105- size_t trackIndex, size_t sampleIndex,
1106- off64_t *offset, size_t *size, bool *isKey,
1107- int64_t *sampleTimeUs) {
1108- if (trackIndex >= mTracks.size()) {
1109- return -ERANGE;
1110- }
1111-
1112- const Track &track = mTracks.itemAt(trackIndex);
1113-
1114- if (sampleIndex >= track.mSamples.size()) {
1115- return -ERANGE;
1116- }
1117-
1118- const SampleInfo &info = track.mSamples.itemAt(sampleIndex);
1119-
1120- if (!mOffsetsAreAbsolute) {
1121- *offset = info.mOffset + mMovieOffset + 8;
1122- } else {
1123- *offset = info.mOffset;
1124- }
1125-
1126- *size = 0;
1127-
1128- uint8_t tmp[8];
1129- ssize_t n = mDataSource->readAt(*offset, tmp, 8);
1130-
1131- if (n < 8) {
1132- return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
1133- }
1134-
1135- uint32_t chunkType = U32_AT(tmp);
1136-
1137- if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) {
1138- return ERROR_MALFORMED;
1139- }
1140-
1141- *offset += 8;
1142- *size = U32LE_AT(&tmp[4]);
1143-
1144- *isKey = info.mIsKey;
1145-
1146- if (track.mBytesPerSample > 0) {
1147- size_t sampleStartInBytes;
1148- if (sampleIndex == 0) {
1149- sampleStartInBytes = 0;
1150- } else {
1151- sampleStartInBytes =
1152- track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1);
1153- }
1154-
1155- sampleIndex = sampleStartInBytes / track.mBytesPerSample;
1156- }
1157-
1158- *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;
1159-
1160- return OK;
1161-}
1162-
1163-status_t AVIExtractor::getSampleTime(
1164- size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
1165- off64_t offset;
1166- size_t size;
1167- bool isKey;
1168- return getSampleInfo(
1169- trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
1170-}
1171-
1172-status_t AVIExtractor::getSampleIndexAtTime(
1173- size_t trackIndex,
1174- int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
1175- size_t *sampleIndex) const {
1176- if (trackIndex >= mTracks.size()) {
1177- return -ERANGE;
1178- }
1179-
1180- const Track &track = mTracks.itemAt(trackIndex);
1181-
1182- ssize_t closestSampleIndex;
1183-
1184- if (track.mBytesPerSample > 0) {
1185- size_t closestByteOffset =
1186- (timeUs * track.mBytesPerSample)
1187- / track.mRate * track.mScale / 1000000ll;
1188-
1189- if (closestByteOffset <= track.mFirstChunkSize) {
1190- closestSampleIndex = 0;
1191- } else {
1192- closestSampleIndex =
1193- (closestByteOffset - track.mFirstChunkSize)
1194- / track.mAvgChunkSize;
1195- }
1196- } else {
1197- // Each chunk contains a single sample.
1198- closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll;
1199- }
1200-
1201- ssize_t numSamples = track.mSamples.size();
1202-
1203- if (closestSampleIndex < 0) {
1204- closestSampleIndex = 0;
1205- } else if (closestSampleIndex >= numSamples) {
1206- closestSampleIndex = numSamples - 1;
1207- }
1208-
1209- if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) {
1210- *sampleIndex = closestSampleIndex;
1211-
1212- return OK;
1213- }
1214-
1215- ssize_t prevSyncSampleIndex = closestSampleIndex;
1216- while (prevSyncSampleIndex >= 0) {
1217- const SampleInfo &info =
1218- track.mSamples.itemAt(prevSyncSampleIndex);
1219-
1220- if (info.mIsKey) {
1221- break;
1222- }
1223-
1224- --prevSyncSampleIndex;
1225- }
1226-
1227- ssize_t nextSyncSampleIndex = closestSampleIndex;
1228- while (nextSyncSampleIndex < numSamples) {
1229- const SampleInfo &info =
1230- track.mSamples.itemAt(nextSyncSampleIndex);
1231-
1232- if (info.mIsKey) {
1233- break;
1234- }
1235-
1236- ++nextSyncSampleIndex;
1237- }
1238-
1239- switch (mode) {
1240- case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC:
1241- {
1242- *sampleIndex = prevSyncSampleIndex;
1243-
1244- return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR;
1245- }
1246-
1247- case MediaSource::ReadOptions::SEEK_NEXT_SYNC:
1248- {
1249- *sampleIndex = nextSyncSampleIndex;
1250-
1251- return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR;
1252- }
1253-
1254- case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC:
1255- {
1256- if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) {
1257- return UNKNOWN_ERROR;
1258- }
1259-
1260- if (prevSyncSampleIndex < 0) {
1261- *sampleIndex = nextSyncSampleIndex;
1262- return OK;
1263- }
1264-
1265- if (nextSyncSampleIndex >= numSamples) {
1266- *sampleIndex = prevSyncSampleIndex;
1267- return OK;
1268- }
1269-
1270- size_t dist1 = closestSampleIndex - prevSyncSampleIndex;
1271- size_t dist2 = nextSyncSampleIndex - closestSampleIndex;
1272-
1273- *sampleIndex =
1274- (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex;
1275-
1276- return OK;
1277- }
1278-
1279- default:
1280- TRESPASS();
1281- break;
1282- }
1283-}
1284-
1285-bool SniffAVI(
1286- const sp<DataSource> &source, String8 *mimeType, float *confidence,
1287- sp<AMessage> *) {
1288- char tmp[12];
1289- if (source->readAt(0, tmp, 12) < 12) {
1290- return false;
1291- }
1292-
1293- if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) {
1294- mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI);
1295-
1296- // Just a tad over the mp3 extractor's confidence, since
1297- // these .avi files may contain .mp3 content that otherwise would
1298- // mistakenly lead to us identifying the entire file as a .mp3 file.
1299- *confidence = 0.21;
1300-
1301- return true;
1302- }
1303-
1304- return false;
1305-}
1306-
1307-} // namespace android
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -129,6 +129,7 @@ cc_library_static {
129129
130130 shared_libs: [
131131 "libstagefright_enc_common",
132+ "liblog",
132133 ],
133134
134135 cflags: ["-Werror"],
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.bp
@@ -12,6 +12,7 @@ cc_test {
1212
1313 shared_libs: [
1414 "libdl",
15+ "liblog",
1516 ],
1617
1718 static_libs: [
--- a/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/c4t64fx.c
@@ -47,6 +47,10 @@
4747
4848 #include "q_pulse.h"
4949
50+#undef LOG_TAG
51+#define LOG_TAG "amrwbenc"
52+#include "log/log.h"
53+
5054 static Word16 tipos[36] = {
5155 0, 1, 2, 3, /* starting point &ipos[0], 1st iter */
5256 1, 2, 3, 0, /* starting point &ipos[4], 2nd iter */
@@ -745,11 +749,16 @@ void ACELP_4t64_fx(
745749
746750 i = (Word16)((vo_L_mult(track, NPMAXPT) >> 1));
747751
748- while (ind[i] >= 0)
752+ while (i < NPMAXPT * NB_TRACK && ind[i] >= 0)
749753 {
750754 i += 1;
751755 }
752- ind[i] = index;
756+ if (i < NPMAXPT * NB_TRACK) {
757+ ind[i] = index;
758+ } else {
759+ ALOGE("b/132647222, OOB access in ind array track=%d i=%d", track, i);
760+ android_errorWriteLog(0x534e4554, "132647222");
761+ }
753762 }
754763
755764 k = 0;
--- a/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/packet_util.cpp
@@ -52,7 +52,11 @@ PV_STATUS PV_ReadVideoPacketHeader(VideoDecData *video, int *next_MB)
5252 PV_BitstreamByteAlign(stream);
5353 BitstreamReadBits32(stream, resync_marker_length);
5454
55- *next_MB = (int) BitstreamReadBits16(stream, nbits);
55+ int mbnum = (int) BitstreamReadBits16(stream, nbits);
56+ if (mbnum < 0) {
57+ return PV_FAIL;
58+ }
59+ *next_MB = mbnum;
5660 // if (*next_MB <= video->mbnum) /* needs more investigation */
5761 // *next_MB = video->mbnum+1;
5862
--- a/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
@@ -1355,6 +1355,14 @@ PV_STATUS DecodeShortHeader(VideoDecData *video, Vop *currVop)
13551355 int tmpHeight = (tmpDisplayHeight + 15) & -16;
13561356 int tmpWidth = (tmpDisplayWidth + 15) & -16;
13571357
1358+ if (tmpWidth > video->width)
1359+ {
1360+ // while allowed by the spec, this decoder does not actually
1361+ // support an increase in size.
1362+ ALOGE("width increase not supported");
1363+ status = PV_FAIL;
1364+ goto return_point;
1365+ }
13581366 if (tmpHeight * tmpWidth > video->size)
13591367 {
13601368 // This is just possibly "b/37079296".
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -157,6 +157,12 @@ ssize_t HTTPDownloader::fetchBlock(
157157 buffer->size() + bufferRemaining);
158158
159159 sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
160+ if (copy->data() == NULL) {
161+ android_errorWriteLog(0x534e4554, "68399439");
162+ ALOGE("not enough memory to download: requesting %zu + %zu",
163+ buffer->size(), bufferRemaining);
164+ return NO_MEMORY;
165+ }
160166 memcpy(copy->data(), buffer->data(), buffer->size());
161167 copy->setRange(0, buffer->size());
162168
--- a/media/libstagefright/omx/1.0/WGraphicBufferProducer.cpp
+++ b/media/libstagefright/omx/1.0/WGraphicBufferProducer.cpp
@@ -40,7 +40,7 @@ Return<void> TWGraphicBufferProducer::requestBuffer(
4040 int32_t slot, requestBuffer_cb _hidl_cb) {
4141 sp<GraphicBuffer> buf;
4242 status_t status = mBase->requestBuffer(slot, &buf);
43- AnwBuffer anwBuffer;
43+ AnwBuffer anwBuffer{};
4444 if (buf != nullptr) {
4545 wrapAs(&anwBuffer, *buf);
4646 }
@@ -62,15 +62,15 @@ Return<void> TWGraphicBufferProducer::dequeueBuffer(
6262 uint32_t width, uint32_t height,
6363 PixelFormat format, uint32_t usage,
6464 bool getFrameTimestamps, dequeueBuffer_cb _hidl_cb) {
65- int slot;
65+ int slot{};
6666 sp<Fence> fence;
6767 ::android::FrameEventHistoryDelta outTimestamps;
6868 status_t status = mBase->dequeueBuffer(
6969 &slot, &fence, width, height,
7070 static_cast<::android::PixelFormat>(format), usage, nullptr,
7171 getFrameTimestamps ? &outTimestamps : nullptr);
72- hidl_handle tFence;
73- FrameEventHistoryDelta tOutTimestamps;
72+ hidl_handle tFence{};
73+ FrameEventHistoryDelta tOutTimestamps{};
7474
7575 native_handle_t* nh = nullptr;
7676 if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
@@ -118,8 +118,8 @@ Return<void> TWGraphicBufferProducer::detachNextBuffer(
118118 sp<GraphicBuffer> outBuffer;
119119 sp<Fence> outFence;
120120 status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
121- AnwBuffer tBuffer;
122- hidl_handle tFence;
121+ AnwBuffer tBuffer{};
122+ hidl_handle tFence{};
123123
124124 if (outBuffer == nullptr) {
125125 LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
@@ -161,7 +161,7 @@ Return<void> TWGraphicBufferProducer::attachBuffer(
161161 Return<void> TWGraphicBufferProducer::queueBuffer(
162162 int32_t slot, const QueueBufferInput& input,
163163 queueBuffer_cb _hidl_cb) {
164- QueueBufferOutput tOutput;
164+ QueueBufferOutput tOutput{};
165165 BGraphicBufferProducer::QueueBufferInput lInput(
166166 0, false, HAL_DATASPACE_UNKNOWN,
167167 ::android::Rect(0, 0, 1, 1),
@@ -223,7 +223,7 @@ Return<void> TWGraphicBufferProducer::connect(
223223 producerControlledByApp,
224224 &lOutput);
225225
226- QueueBufferOutput tOutput;
226+ QueueBufferOutput tOutput{};
227227 std::vector<std::vector<native_handle_t*> > nhAA;
228228 if (!wrapAs(&tOutput, &nhAA, lOutput)) {
229229 LOG(ERROR) << "TWGraphicBufferProducer::connect - "
@@ -295,11 +295,11 @@ Return<void> TWGraphicBufferProducer::getLastQueuedBuffer(
295295 status_t status = mBase->getLastQueuedBuffer(
296296 &lOutBuffer, &lOutFence, lOutTransformMatrix);
297297
298- AnwBuffer tOutBuffer;
298+ AnwBuffer tOutBuffer{};
299299 if (lOutBuffer != nullptr) {
300300 wrapAs(&tOutBuffer, *lOutBuffer);
301301 }
302- hidl_handle tOutFence;
302+ hidl_handle tOutFence{};
303303 native_handle_t* nh = nullptr;
304304 if ((lOutFence == nullptr) || !wrapAs(&tOutFence, &nh, *lOutFence)) {
305305 LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
@@ -322,7 +322,7 @@ Return<void> TWGraphicBufferProducer::getFrameTimestamps(
322322 ::android::FrameEventHistoryDelta lDelta;
323323 mBase->getFrameTimestamps(&lDelta);
324324
325- FrameEventHistoryDelta tDelta;
325+ FrameEventHistoryDelta tDelta{};
326326 std::vector<std::vector<native_handle_t*> > nhAA;
327327 if (!wrapAs(&tDelta, &nhAA, lDelta)) {
328328 LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
@@ -341,7 +341,7 @@ Return<void> TWGraphicBufferProducer::getFrameTimestamps(
341341 }
342342
343343 Return<void> TWGraphicBufferProducer::getUniqueId(getUniqueId_cb _hidl_cb) {
344- uint64_t outId;
344+ uint64_t outId{};
345345 status_t status = mBase->getUniqueId(&outId);
346346 _hidl_cb(static_cast<int32_t>(status), outId);
347347 return Void();
--- a/media/libstagefright/timedtext/TextDescriptions.cpp
+++ b/media/libstagefright/timedtext/TextDescriptions.cpp
@@ -383,7 +383,7 @@ status_t TextDescriptions::extract3GPPGlobalDescriptions(
383383 tmpData += 8;
384384 size_t remaining = size - 8;
385385
386- if (size < chunkSize) {
386+ if (chunkSize <= 8 || size < chunkSize) {
387387 return OK;
388388 }
389389 switch(chunkType) {
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2987,9 +2987,13 @@ sp<IEffect> AudioFlinger::createEffect(
29872987 }
29882988 // look for the thread where the specified audio session is present
29892989 for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
2990- if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
2990+ uint32_t sessionType = mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
2991+ if (sessionType != 0) {
29912992 io = mPlaybackThreads.keyAt(i);
2992- break;
2993+ // thread with same effect session is preferable
2994+ if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) {
2995+ break;
2996+ }
29932997 }
29942998 }
29952999 if (io == AUDIO_IO_HANDLE_NONE) {
@@ -3015,6 +3019,21 @@ sp<IEffect> AudioFlinger::createEffect(
30153019 io = mPlaybackThreads.keyAt(0);
30163020 }
30173021 ALOGV("createEffect() got io %d for effect %s", io, desc.name);
3022+ } else if (checkPlaybackThread_l(io) != nullptr) {
3023+ // allow only one effect chain per sessionId on mPlaybackThreads.
3024+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
3025+ const audio_io_handle_t checkIo = mPlaybackThreads.keyAt(i);
3026+ if (io == checkIo) continue;
3027+ const uint32_t sessionType =
3028+ mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId);
3029+ if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) {
3030+ ALOGE("%s: effect %s io %d denied because session %d effect exists on io %d",
3031+ __func__, desc.name, (int)io, (int)sessionId, (int)checkIo);
3032+ android_errorWriteLog(0x534e4554, "123237974");
3033+ lStatus = BAD_VALUE;
3034+ goto Exit;
3035+ }
3036+ }
30183037 }
30193038 ThreadBase *thread = checkRecordThread_l(io);
30203039 if (thread == NULL) {
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -27,7 +27,7 @@
2727 namespace android {
2828
2929 class IOProfile;
30-class AudioMix;
30+class AudioPolicyMix;
3131
3232 // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
3333 // and keep track of the usage of this input.
@@ -44,7 +44,7 @@ public:
4444
4545 audio_io_handle_t mIoHandle; // input handle
4646 audio_devices_t mDevice; // current device this input is routed to
47- AudioMix *mPolicyMix; // non NULL when used by a dynamic policy
47+ wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
4848 const sp<IOProfile> mProfile; // I/O profile this output derives from
4949
5050 virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -29,7 +29,7 @@
2929 namespace android {
3030
3131 class IOProfile;
32-class AudioMix;
32+class AudioPolicyMix;
3333 class AudioPolicyClientInterface;
3434 class DeviceDescriptor;
3535
@@ -126,7 +126,7 @@ public:
126126 audio_io_handle_t mIoHandle; // output handle
127127 uint32_t mLatency; //
128128 audio_output_flags_t mFlags; //
129- AudioMix *mPolicyMix; // non NULL when used by a dynamic policy
129+ wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
130130 sp<SwAudioOutputDescriptor> mOutput1; // used by duplicated outputs: first output
131131 sp<SwAudioOutputDescriptor> mOutput2; // used by duplicated outputs: second output
132132 uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -29,9 +29,11 @@ class SwAudioOutputDescriptor;
2929 /**
3030 * custom mix entry in mPolicyMixes
3131 */
32-class AudioPolicyMix : public RefBase {
32+class AudioPolicyMix : public AudioMix, public RefBase {
3333 public:
34- AudioPolicyMix() {}
34+ AudioPolicyMix(const AudioMix &mix);
35+ AudioPolicyMix(const AudioPolicyMix&) = delete;
36+ AudioPolicyMix& operator=(const AudioPolicyMix&) = delete;
3537
3638 const sp<SwAudioOutputDescriptor> &getOutput() const;
3739
@@ -39,14 +41,9 @@ public:
3941
4042 void clearOutput();
4143
42- android::AudioMix *getMix();
43-
44- void setMix(AudioMix &mix);
45-
4644 status_t dump(int fd, int spaces, int index) const;
4745
4846 private:
49- AudioMix mMix; // Audio policy mix descriptor
5047 sp<SwAudioOutputDescriptor> mOutput; // Corresponding output stream
5148 };
5249
@@ -76,9 +73,9 @@ public:
7673
7774 audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
7875 audio_devices_t availableDeviceTypes,
79- AudioMix **policyMix);
76+ sp<AudioPolicyMix> *policyMix);
8077
81- status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
78+ status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix);
8279
8380 status_t dump(int fd) const;
8481 };
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -28,6 +28,7 @@
2828 namespace android {
2929
3030 class AudioPolicyClientInterface;
31+class AudioPolicyMix;
3132
3233 class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
3334 {
@@ -40,7 +41,7 @@ public:
4041 audio_input_flags_t flags,
4142 uid_t uid,
4243 bool isSoundTrigger,
43- AudioMix* policyMix,
44+ const sp<AudioPolicyMix> &policyMix,
4445 AudioPolicyClientInterface *clientInterface);
4546
4647 status_t dump(int fd, int spaces, int index) const;
@@ -72,7 +73,7 @@ private:
7273 bool mIsSoundTrigger;
7374 uint32_t mOpenCount;
7475 uint32_t mActiveCount;
75- AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
76+ wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
7677 AudioPolicyClientInterface* mClientInterface;
7778 const AudioSessionInfoProvider* mInfoProvider;
7879 };
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -20,6 +20,7 @@
2020 #include "AudioInputDescriptor.h"
2121 #include "IOProfile.h"
2222 #include "AudioGain.h"
23+#include "AudioPolicyMix.h"
2324 #include "HwModule.h"
2425 #include <media/AudioPolicy.h>
2526 #include <policy.h>
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -19,6 +19,7 @@
1919
2020 #include <AudioPolicyInterface.h>
2121 #include "AudioOutputDescriptor.h"
22+#include "AudioPolicyMix.h"
2223 #include "IOProfile.h"
2324 #include "AudioGain.h"
2425 #include "Volume.h"
@@ -313,17 +314,18 @@ void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
313314 } else {
314315 mGlobalRefCount += delta;
315316 }
317+ sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
316318 if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
317- if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
319+ if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
318320 {
319- mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
321+ mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
320322 MIX_STATE_MIXING);
321323 }
322324
323325 } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
324- if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
326+ if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
325327 {
326- mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
328+ mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
327329 MIX_STATE_IDLE);
328330 }
329331 }
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -27,6 +27,10 @@
2727
2828 namespace android {
2929
30+AudioPolicyMix::AudioPolicyMix(const AudioMix &mix) : AudioMix(mix)
31+{
32+}
33+
3034 void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
3135 {
3236 mOutput = output;
@@ -42,16 +46,6 @@ void AudioPolicyMix::clearOutput()
4246 mOutput.clear();
4347 }
4448
45-void AudioPolicyMix::setMix(AudioMix &mix)
46-{
47- mMix = mix;
48-}
49-
50-android::AudioMix *AudioPolicyMix::getMix()
51-{
52- return &mMix;
53-}
54-
5549 status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
5650 {
5751 const size_t SIZE = 256;
@@ -61,25 +55,25 @@ status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
6155 snprintf(buffer, SIZE, "%*sAudio Policy Mix %d:\n", spaces, "", index+1);
6256 result.append(buffer);
6357 std::string mixTypeLiteral;
64- if (!MixTypeConverter::toString(mMix.mMixType, mixTypeLiteral)) {
65- ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMix.mMixType);
58+ if (!MixTypeConverter::toString(mMixType, mixTypeLiteral)) {
59+ ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMixType);
6660 return BAD_VALUE;
6761 }
6862 snprintf(buffer, SIZE, "%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
6963 result.append(buffer);
7064 std::string routeFlagLiteral;
71- RouteFlagTypeConverter::maskToString(mMix.mRouteFlags, routeFlagLiteral);
65+ RouteFlagTypeConverter::maskToString(mRouteFlags, routeFlagLiteral);
7266 snprintf(buffer, SIZE, "%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
7367 result.append(buffer);
7468 std::string deviceLiteral;
75- deviceToString(mMix.mDeviceType, deviceLiteral);
69+ deviceToString(mDeviceType, deviceLiteral);
7670 snprintf(buffer, SIZE, "%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
7771 result.append(buffer);
78- snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
72+ snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
7973 result.append(buffer);
8074
8175 int indexCriterion = 0;
82- for (const auto &criterion : mMix.mCriteria) {
76+ for (const auto &criterion : mCriteria) {
8377 snprintf(buffer, SIZE, "%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
8478 result.append(buffer);
8579 std::string usageLiteral;
@@ -89,7 +83,7 @@ status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
8983 }
9084 snprintf(buffer, SIZE, "%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
9185 result.append(buffer);
92- if (mMix.mMixType == MIX_TYPE_RECORDERS) {
86+ if (mMixType == MIX_TYPE_RECORDERS) {
9387 std::string sourceLiteral;
9488 if (!SourceTypeConverter::toString(criterion.mValue.mSource, sourceLiteral)) {
9589 ALOGE("%s: failed to convert source %d", __FUNCTION__, criterion.mValue.mSource);
@@ -120,12 +114,11 @@ status_t AudioPolicyMixCollection::registerMix(const String8& address, AudioMix
120114 ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string());
121115 return BAD_VALUE;
122116 }
123- sp<AudioPolicyMix> policyMix = new AudioPolicyMix();
124- policyMix->setMix(mix);
117+ sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
125118 add(address, policyMix);
126119
127120 if (desc != 0) {
128- desc->mPolicyMix = policyMix->getMix();
121+ desc->mPolicyMix = policyMix;
129122 policyMix->setOutput(desc);
130123 }
131124 return NO_ERROR;
@@ -171,8 +164,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
171164 ALOGV("getOutputForAttr() querying %zu mixes:", size());
172165 desc = 0;
173166 for (size_t i = 0; i < size(); i++) {
174- sp<AudioPolicyMix> policyMix = valueAt(i);
175- AudioMix *mix = policyMix->getMix();
167+ sp<AudioPolicyMix> mix = valueAt(i);
176168
177169 if (mix->mMixType == MIX_TYPE_PLAYERS) {
178170 // TODO if adding more player rules (currently only 2), make rule handling "generic"
@@ -269,7 +261,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
269261 (hasUidExcludeRules && uidExclusionFound) ||
270262 (hasUidMatchRules && !uidMatchFound))) {
271263 ALOGV("\tgetOutputForAttr will use mix %zu", i);
272- desc = policyMix->getOutput();
264+ desc = mix->getOutput();
273265 }
274266
275267 } else if (mix->mMixType == MIX_TYPE_RECORDERS) {
@@ -278,7 +270,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
278270 strncmp(attributes.tags + strlen("addr="),
279271 mix->mDeviceAddress.string(),
280272 AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
281- desc = policyMix->getOutput();
273+ desc = mix->getOutput();
282274 }
283275 }
284276 if (desc != 0) {
@@ -289,12 +281,13 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
289281 return BAD_VALUE;
290282 }
291283
292-audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_source_t inputSource,
293- audio_devices_t availDevices,
294- AudioMix **policyMix)
284+audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(
285+ audio_source_t inputSource,
286+ audio_devices_t availDevices,
287+ sp<AudioPolicyMix> *policyMix)
295288 {
296289 for (size_t i = 0; i < size(); i++) {
297- AudioMix *mix = valueAt(i)->getMix();
290+ AudioPolicyMix *mix = valueAt(i).get();
298291
299292 if (mix->mMixType != MIX_TYPE_RECORDERS) {
300293 continue;
@@ -317,7 +310,8 @@ audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_so
317310 return AUDIO_DEVICE_NONE;
318311 }
319312
320-status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix)
313+status_t AudioPolicyMixCollection::getInputMixForAttr(
314+ audio_attributes_t attr, sp<AudioPolicyMix> *policyMix)
321315 {
322316 if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) {
323317 return BAD_VALUE;
@@ -327,8 +321,7 @@ status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, A
327321 #ifdef LOG_NDEBUG
328322 ALOGV("getInputMixForAttr looking for address %s\n mixes available:", address.string());
329323 for (size_t i = 0; i < size(); i++) {
330- sp<AudioPolicyMix> policyMix = valueAt(i);
331- AudioMix *mix = policyMix->getMix();
324+ sp<AudioPolicyMix> mix = valueAt(i);
332325 ALOGV("\tmix %zu address=%s", i, mix->mDeviceAddress.string());
333326 }
334327 #endif
@@ -339,13 +332,14 @@ status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, A
339332 return BAD_VALUE;
340333 }
341334 sp<AudioPolicyMix> audioPolicyMix = valueAt(index);
342- AudioMix *mix = audioPolicyMix->getMix();
343335
344- if (mix->mMixType != MIX_TYPE_PLAYERS) {
336+ if (audioPolicyMix->mMixType != MIX_TYPE_PLAYERS) {
345337 ALOGW("getInputMixForAttr() bad policy mix type for address %s", address.string());
346338 return BAD_VALUE;
347339 }
348- *policyMix = mix;
340+ if (policyMix != nullptr) {
341+ *policyMix = audioPolicyMix;
342+ }
349343 return NO_ERROR;
350344 }
351345
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -19,6 +19,7 @@
1919
2020 #include <AudioPolicyInterface.h>
2121 #include "policy.h"
22+#include "AudioPolicyMix.h"
2223 #include "AudioSession.h"
2324 #include "AudioGain.h"
2425 #include "TypeConverter.h"
@@ -36,7 +37,7 @@ AudioSession::AudioSession(audio_session_t session,
3637 audio_input_flags_t flags,
3738 uid_t uid,
3839 bool isSoundTrigger,
39- AudioMix* policyMix,
40+ const sp<AudioPolicyMix> &policyMix,
4041 AudioPolicyClientInterface *clientInterface) :
4142 mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
4243 mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
@@ -79,9 +80,10 @@ uint32_t AudioSession::changeActiveCount(int delta)
7980 if (event != RECORD_CONFIG_EVENT_NONE) {
8081 // Dynamic policy callback:
8182 // if input maps to a dynamic policy with an activity listener, notify of state change
82- if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
83+ sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
84+ if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
8385 {
84- mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
86+ mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
8587 (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
8688 }
8789
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1197,10 +1197,9 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
11971197 mOutputRoutes.incRouteActivity(session);
11981198
11991199 audio_devices_t newDevice;
1200- AudioMix *policyMix = NULL;
1200+ sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
12011201 const char *address = NULL;
1202- if (outputDesc->mPolicyMix != NULL) {
1203- policyMix = outputDesc->mPolicyMix;
1202+ if (policyMix != NULL) {
12041203 address = policyMix->mDeviceAddress.string();
12051204 if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
12061205 newDevice = policyMix->mDeviceType;
@@ -1358,12 +1357,13 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
13581357 if (outputDesc->mRefCount[stream] == 1) {
13591358 // Automatically disable the remote submix input when output is stopped on a
13601359 // re routing mix of type MIX_TYPE_RECORDERS
1360+ sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
13611361 if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1362- outputDesc->mPolicyMix != NULL &&
1363- outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1362+ policyMix != NULL &&
1363+ policyMix->mMixType == MIX_TYPE_RECORDERS) {
13641364 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
13651365 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1366- outputDesc->mPolicyMix->mDeviceAddress,
1366+ policyMix->mDeviceAddress,
13671367 "remote-submix");
13681368 }
13691369 }
@@ -1504,7 +1504,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
15041504 String8 address = String8("");
15051505 audio_source_t halInputSource;
15061506 audio_source_t inputSource = attr->source;
1507- AudioMix *policyMix = NULL;
1507+ sp<AudioPolicyMix> policyMix;
15081508 DeviceVector inputDevices;
15091509
15101510 // Explicit routing?
@@ -1646,7 +1646,7 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
16461646 audio_format_t format,
16471647 audio_channel_mask_t channelMask,
16481648 audio_input_flags_t flags,
1649- AudioMix *policyMix)
1649+ const sp<AudioPolicyMix> &policyMix)
16501650 {
16511651 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
16521652 audio_source_t halInputSource = inputSource;
@@ -2028,10 +2028,11 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
20282028 setInputDevice(input, device, true /* force */);
20292029
20302030 if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
2031+ sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
20312032 // if input maps to a dynamic policy with an activity listener, notify of state change
2032- if ((inputDesc->mPolicyMix != NULL)
2033- && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2034- mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
2033+ if ((policyMix != NULL)
2034+ && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2035+ mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
20352036 MIX_STATE_MIXING);
20362037 }
20372038
@@ -2046,10 +2047,10 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
20462047 // For remote submix (a virtual device), we open only one input per capture request.
20472048 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
20482049 String8 address = String8("");
2049- if (inputDesc->mPolicyMix == NULL) {
2050+ if (policyMix == NULL) {
20502051 address = String8("0");
2051- } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
2052- address = inputDesc->mPolicyMix->mDeviceAddress;
2052+ } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
2053+ address = policyMix->mDeviceAddress;
20532054 }
20542055 if (address != "") {
20552056 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
@@ -2097,10 +2098,11 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
20972098 if (inputDesc->isActive()) {
20982099 setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
20992100 } else {
2101+ sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
21002102 // if input maps to a dynamic policy with an activity listener, notify of state change
2101- if ((inputDesc->mPolicyMix != NULL)
2102- && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2103- mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
2103+ if ((policyMix != NULL)
2104+ && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2105+ mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
21042106 MIX_STATE_IDLE);
21052107 }
21062108
@@ -2108,10 +2110,10 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
21082110 // used by a policy mix of type MIX_TYPE_RECORDERS
21092111 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
21102112 String8 address = String8("");
2111- if (inputDesc->mPolicyMix == NULL) {
2113+ if (policyMix == NULL) {
21122114 address = String8("0");
2113- } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
2114- address = inputDesc->mPolicyMix->mDeviceAddress;
2115+ } else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
2116+ address = policyMix->mDeviceAddress;
21152117 }
21162118 if (address != "") {
21172119 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
@@ -4211,7 +4213,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
42114213 address.string());
42124214 }
42134215 policyMix->setOutput(desc);
4214- desc->mPolicyMix = policyMix->getMix();
4216+ desc->mPolicyMix = policyMix;
42154217
42164218 } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
42174219 hasPrimaryOutput()) {
@@ -5325,7 +5327,7 @@ sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
53255327
53265328
53275329 audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
5328- AudioMix **policyMix)
5330+ sp<AudioPolicyMix> *policyMix)
53295331 {
53305332 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
53315333 audio_devices_t selectedDeviceFromMix =
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -645,7 +645,7 @@ private:
645645 audio_format_t format,
646646 audio_channel_mask_t channelMask,
647647 audio_input_flags_t flags,
648- AudioMix *policyMix);
648+ const sp<AudioPolicyMix> &policyMix);
649649
650650 // internal function to derive a stream type value from audio attributes
651651 audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr);
@@ -659,7 +659,7 @@ private:
659659 // select input device corresponding to requested audio source and return associated policy
660660 // mix if any. Calls getDeviceForInputSource().
661661 audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
662- AudioMix **policyMix = NULL);
662+ sp<AudioPolicyMix> *policyMix = NULL);
663663
664664 // Called by setDeviceConnectionState().
665665 status_t setDeviceConnectionStateInt(audio_devices_t device,
Show on old repository browser