Utils.cpp revision 2829edccd7d2bb8244246f316face82b650b8949
1/*
2 * Copyright (C) 2009 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 "Utils"
19#include <utils/Log.h>
20#include <ctype.h>
21
22#include "include/ESDS.h"
23
24#include <arpa/inet.h>
25#include <cutils/properties.h>
26#include <media/openmax/OMX_Audio.h>
27#include <media/stagefright/foundation/ABuffer.h>
28#include <media/stagefright/foundation/ADebug.h>
29#include <media/stagefright/foundation/AMessage.h>
30#include <media/stagefright/MetaData.h>
31#include <media/stagefright/MediaDefs.h>
32#include <media/AudioSystem.h>
33#include <media/MediaPlayerInterface.h>
34#include <hardware/audio.h>
35#include <media/stagefright/Utils.h>
36#include <media/AudioParameter.h>
37
38namespace android {
39
40uint16_t U16_AT(const uint8_t *ptr) {
41    return ptr[0] << 8 | ptr[1];
42}
43
44uint32_t U32_AT(const uint8_t *ptr) {
45    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
46}
47
48uint64_t U64_AT(const uint8_t *ptr) {
49    return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
50}
51
52uint16_t U16LE_AT(const uint8_t *ptr) {
53    return ptr[0] | (ptr[1] << 8);
54}
55
56uint32_t U32LE_AT(const uint8_t *ptr) {
57    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
58}
59
60uint64_t U64LE_AT(const uint8_t *ptr) {
61    return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
62}
63
64// XXX warning: these won't work on big-endian host.
65uint64_t ntoh64(uint64_t x) {
66    return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
67}
68
69uint64_t hton64(uint64_t x) {
70    return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
71}
72
73status_t convertMetaDataToMessage(
74        const sp<MetaData> &meta, sp<AMessage> *format) {
75    format->clear();
76
77    const char *mime;
78    CHECK(meta->findCString(kKeyMIMEType, &mime));
79
80    sp<AMessage> msg = new AMessage;
81    msg->setString("mime", mime);
82
83    int64_t durationUs;
84    if (meta->findInt64(kKeyDuration, &durationUs)) {
85        msg->setInt64("durationUs", durationUs);
86    }
87
88    int avgBitRate;
89    if (meta->findInt32(kKeyBitRate, &avgBitRate)) {
90        msg->setInt32("bit-rate", avgBitRate);
91    }
92
93    int32_t isSync;
94    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
95        msg->setInt32("is-sync-frame", 1);
96    }
97
98    if (!strncasecmp("video/", mime, 6)) {
99        int32_t width, height;
100        CHECK(meta->findInt32(kKeyWidth, &width));
101        CHECK(meta->findInt32(kKeyHeight, &height));
102
103        msg->setInt32("width", width);
104        msg->setInt32("height", height);
105
106        int32_t sarWidth, sarHeight;
107        if (meta->findInt32(kKeySARWidth, &sarWidth)
108                && meta->findInt32(kKeySARHeight, &sarHeight)) {
109            msg->setInt32("sar-width", sarWidth);
110            msg->setInt32("sar-height", sarHeight);
111        }
112    } else if (!strncasecmp("audio/", mime, 6)) {
113        int32_t numChannels, sampleRate;
114        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
115        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
116
117        msg->setInt32("channel-count", numChannels);
118        msg->setInt32("sample-rate", sampleRate);
119
120        int32_t channelMask;
121        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
122            msg->setInt32("channel-mask", channelMask);
123        }
124
125        int32_t delay = 0;
126        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
127            msg->setInt32("encoder-delay", delay);
128        }
129        int32_t padding = 0;
130        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
131            msg->setInt32("encoder-padding", padding);
132        }
133
134        int32_t isADTS;
135        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
136            msg->setInt32("is-adts", true);
137        }
138    }
139
140    int32_t maxInputSize;
141    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
142        msg->setInt32("max-input-size", maxInputSize);
143    }
144
145    uint32_t type;
146    const void *data;
147    size_t size;
148    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
149        // Parse the AVCDecoderConfigurationRecord
150
151        const uint8_t *ptr = (const uint8_t *)data;
152
153        CHECK(size >= 7);
154        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
155        uint8_t profile = ptr[1];
156        uint8_t level = ptr[3];
157
158        // There is decodable content out there that fails the following
159        // assertion, let's be lenient for now...
160        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
161
162        size_t lengthSize = 1 + (ptr[4] & 3);
163
164        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
165        // violates it...
166        // CHECK((ptr[5] >> 5) == 7);  // reserved
167
168        size_t numSeqParameterSets = ptr[5] & 31;
169
170        ptr += 6;
171        size -= 6;
172
173        sp<ABuffer> buffer = new ABuffer(1024);
174        buffer->setRange(0, 0);
175
176        for (size_t i = 0; i < numSeqParameterSets; ++i) {
177            CHECK(size >= 2);
178            size_t length = U16_AT(ptr);
179
180            ptr += 2;
181            size -= 2;
182
183            CHECK(size >= length);
184
185            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
186            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
187            buffer->setRange(0, buffer->size() + 4 + length);
188
189            ptr += length;
190            size -= length;
191        }
192
193        buffer->meta()->setInt32("csd", true);
194        buffer->meta()->setInt64("timeUs", 0);
195
196        msg->setBuffer("csd-0", buffer);
197
198        buffer = new ABuffer(1024);
199        buffer->setRange(0, 0);
200
201        CHECK(size >= 1);
202        size_t numPictureParameterSets = *ptr;
203        ++ptr;
204        --size;
205
206        for (size_t i = 0; i < numPictureParameterSets; ++i) {
207            CHECK(size >= 2);
208            size_t length = U16_AT(ptr);
209
210            ptr += 2;
211            size -= 2;
212
213            CHECK(size >= length);
214
215            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
216            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
217            buffer->setRange(0, buffer->size() + 4 + length);
218
219            ptr += length;
220            size -= length;
221        }
222
223        buffer->meta()->setInt32("csd", true);
224        buffer->meta()->setInt64("timeUs", 0);
225        msg->setBuffer("csd-1", buffer);
226    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
227        const uint8_t *ptr = (const uint8_t *)data;
228
229        CHECK(size >= 7);
230        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
231        uint8_t profile = ptr[1] & 31;
232        uint8_t level = ptr[12];
233        ptr += 22;
234        size -= 22;
235
236
237        size_t numofArrays = (char)ptr[0];
238        ptr += 1;
239        size -= 1;
240        size_t j = 0, i = 0;
241
242        sp<ABuffer> buffer = new ABuffer(1024);
243        buffer->setRange(0, 0);
244
245        for (i = 0; i < numofArrays; i++) {
246            ptr += 1;
247            size -= 1;
248
249            //Num of nals
250            size_t numofNals = U16_AT(ptr);
251
252            ptr += 2;
253            size -= 2;
254
255            for (j = 0; j < numofNals; j++) {
256                CHECK(size >= 2);
257                size_t length = U16_AT(ptr);
258
259                ptr += 2;
260                size -= 2;
261
262                CHECK(size >= length);
263
264                memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
265                memcpy(buffer->data() + buffer->size() + 4, ptr, length);
266                buffer->setRange(0, buffer->size() + 4 + length);
267
268                ptr += length;
269                size -= length;
270            }
271        }
272        buffer->meta()->setInt32("csd", true);
273        buffer->meta()->setInt64("timeUs", 0);
274        msg->setBuffer("csd-0", buffer);
275
276    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
277        ESDS esds((const char *)data, size);
278        CHECK_EQ(esds.InitCheck(), (status_t)OK);
279
280        const void *codec_specific_data;
281        size_t codec_specific_data_size;
282        esds.getCodecSpecificInfo(
283                &codec_specific_data, &codec_specific_data_size);
284
285        sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
286
287        memcpy(buffer->data(), codec_specific_data,
288               codec_specific_data_size);
289
290        buffer->meta()->setInt32("csd", true);
291        buffer->meta()->setInt64("timeUs", 0);
292        msg->setBuffer("csd-0", buffer);
293    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
294        sp<ABuffer> buffer = new ABuffer(size);
295        memcpy(buffer->data(), data, size);
296
297        buffer->meta()->setInt32("csd", true);
298        buffer->meta()->setInt64("timeUs", 0);
299        msg->setBuffer("csd-0", buffer);
300
301        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
302            return -EINVAL;
303        }
304
305        buffer = new ABuffer(size);
306        memcpy(buffer->data(), data, size);
307
308        buffer->meta()->setInt32("csd", true);
309        buffer->meta()->setInt64("timeUs", 0);
310        msg->setBuffer("csd-1", buffer);
311    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
312        sp<ABuffer> buffer = new ABuffer(size);
313        memcpy(buffer->data(), data, size);
314
315        buffer->meta()->setInt32("csd", true);
316        buffer->meta()->setInt64("timeUs", 0);
317        msg->setBuffer("csd-0", buffer);
318    }
319
320    *format = msg;
321
322    return OK;
323}
324
325static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
326
327    avcc[0] = 1;        // version
328    avcc[1] = 0x64;     // profile
329    avcc[2] = 0;        // unused (?)
330    avcc[3] = 0xd;      // level
331    avcc[4] = 0xff;     // reserved+size
332
333    size_t i = 0;
334    int numparams = 0;
335    int lastparamoffset = 0;
336    int avccidx = 6;
337    do {
338        if (i >= csd0->size() - 4 ||
339                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
340            if (i >= csd0->size() - 4) {
341                // there can't be another param here, so use all the rest
342                i = csd0->size();
343            }
344            ALOGV("block at %zu, last was %d", i, lastparamoffset);
345            if (lastparamoffset > 0) {
346                int size = i - lastparamoffset;
347                avcc[avccidx++] = size >> 8;
348                avcc[avccidx++] = size & 0xff;
349                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
350                avccidx += size;
351                numparams++;
352            }
353            i += 4;
354            lastparamoffset = i;
355        } else {
356            i++;
357        }
358    } while(i < csd0->size());
359    ALOGV("csd0 contains %d params", numparams);
360
361    avcc[5] = 0xe0 | numparams;
362    //and now csd-1
363    i = 0;
364    numparams = 0;
365    lastparamoffset = 0;
366    int numpicparamsoffset = avccidx;
367    avccidx++;
368    do {
369        if (i >= csd1->size() - 4 ||
370                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
371            if (i >= csd1->size() - 4) {
372                // there can't be another param here, so use all the rest
373                i = csd1->size();
374            }
375            ALOGV("block at %zu, last was %d", i, lastparamoffset);
376            if (lastparamoffset > 0) {
377                int size = i - lastparamoffset;
378                avcc[avccidx++] = size >> 8;
379                avcc[avccidx++] = size & 0xff;
380                memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
381                avccidx += size;
382                numparams++;
383            }
384            i += 4;
385            lastparamoffset = i;
386        } else {
387            i++;
388        }
389    } while(i < csd1->size());
390    avcc[numpicparamsoffset] = numparams;
391    return avccidx;
392}
393
394static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
395    int csd0size = csd0->size();
396    esds[0] = 3; // kTag_ESDescriptor;
397    int esdescriptorsize = 26 + csd0size;
398    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
399    esds[1] = 0x80 | (esdescriptorsize >> 21);
400    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
401    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
402    esds[4] = (esdescriptorsize & 0x7f);
403    esds[5] = esds[6] = 0; // es id
404    esds[7] = 0; // flags
405    esds[8] = 4; // kTag_DecoderConfigDescriptor
406    int configdescriptorsize = 18 + csd0size;
407    esds[9] = 0x80 | (configdescriptorsize >> 21);
408    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
409    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
410    esds[12] = (configdescriptorsize & 0x7f);
411    esds[13] = 0x40; // objectTypeIndication
412    esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
413    esds[15] = 0x00; // but the actual values here were taken from a real file.
414    esds[16] = 0x18;
415    esds[17] = 0x00;
416    esds[18] = 0x00;
417    esds[19] = 0x00;
418    esds[20] = 0xfa;
419    esds[21] = 0x00;
420    esds[22] = 0x00;
421    esds[23] = 0x00;
422    esds[24] = 0xfa;
423    esds[25] = 0x00;
424    esds[26] = 5; // kTag_DecoderSpecificInfo;
425    esds[27] = 0x80 | (csd0size >> 21);
426    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
427    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
428    esds[30] = (csd0size & 0x7f);
429    memcpy((void*)&esds[31], csd0->data(), csd0size);
430    // data following this is ignored, so don't bother appending it
431
432}
433
434void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
435    AString mime;
436    if (msg->findString("mime", &mime)) {
437        meta->setCString(kKeyMIMEType, mime.c_str());
438    } else {
439        ALOGW("did not find mime type");
440    }
441
442    int64_t durationUs;
443    if (msg->findInt64("durationUs", &durationUs)) {
444        meta->setInt64(kKeyDuration, durationUs);
445    }
446
447    int32_t isSync;
448    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
449        meta->setInt32(kKeyIsSyncFrame, 1);
450    }
451
452    if (mime.startsWith("video/")) {
453        int32_t width;
454        int32_t height;
455        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
456            meta->setInt32(kKeyWidth, width);
457            meta->setInt32(kKeyHeight, height);
458        } else {
459            ALOGW("did not find width and/or height");
460        }
461
462        int32_t sarWidth, sarHeight;
463        if (msg->findInt32("sar-width", &sarWidth)
464                && msg->findInt32("sar-height", &sarHeight)) {
465            meta->setInt32(kKeySARWidth, sarWidth);
466            meta->setInt32(kKeySARHeight, sarHeight);
467        }
468    } else if (mime.startsWith("audio/")) {
469        int32_t numChannels;
470        if (msg->findInt32("channel-count", &numChannels)) {
471            meta->setInt32(kKeyChannelCount, numChannels);
472        }
473        int32_t sampleRate;
474        if (msg->findInt32("sample-rate", &sampleRate)) {
475            meta->setInt32(kKeySampleRate, sampleRate);
476        }
477        int32_t channelMask;
478        if (msg->findInt32("channel-mask", &channelMask)) {
479            meta->setInt32(kKeyChannelMask, channelMask);
480        }
481        int32_t delay = 0;
482        if (msg->findInt32("encoder-delay", &delay)) {
483            meta->setInt32(kKeyEncoderDelay, delay);
484        }
485        int32_t padding = 0;
486        if (msg->findInt32("encoder-padding", &padding)) {
487            meta->setInt32(kKeyEncoderPadding, padding);
488        }
489
490        int32_t isADTS;
491        if (msg->findInt32("is-adts", &isADTS)) {
492            meta->setInt32(kKeyIsADTS, isADTS);
493        }
494    }
495
496    int32_t maxInputSize;
497    if (msg->findInt32("max-input-size", &maxInputSize)) {
498        meta->setInt32(kKeyMaxInputSize, maxInputSize);
499    }
500
501    // reassemble the csd data into its original form
502    sp<ABuffer> csd0;
503    if (msg->findBuffer("csd-0", &csd0)) {
504        if (mime.startsWith("video/")) { // do we need to be stricter than this?
505            sp<ABuffer> csd1;
506            if (msg->findBuffer("csd-1", &csd1)) {
507                char avcc[1024]; // that oughta be enough, right?
508                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
509                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
510            }
511        } else if (mime.startsWith("audio/")) {
512            int csd0size = csd0->size();
513            char esds[csd0size + 31];
514            reassembleESDS(csd0, esds);
515            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
516        }
517    }
518
519    int32_t timeScale;
520    if (msg->findInt32("time-scale", &timeScale)) {
521        meta->setInt32(kKeyTimeScale, timeScale);
522    }
523
524    // XXX TODO add whatever other keys there are
525
526#if 0
527    ALOGI("converted %s to:", msg->debugString(0).c_str());
528    meta->dumpToLog();
529#endif
530}
531
532AString MakeUserAgent() {
533    AString ua;
534    ua.append("stagefright/1.2 (Linux;Android ");
535
536#if (PROPERTY_VALUE_MAX < 8)
537#error "PROPERTY_VALUE_MAX must be at least 8"
538#endif
539
540    char value[PROPERTY_VALUE_MAX];
541    property_get("ro.build.version.release", value, "Unknown");
542    ua.append(value);
543    ua.append(")");
544
545    return ua;
546}
547
548status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
549                           const sp<MetaData>& meta)
550{
551    int32_t sampleRate = 0;
552    int32_t bitRate = 0;
553    int32_t channelMask = 0;
554    int32_t delaySamples = 0;
555    int32_t paddingSamples = 0;
556
557    AudioParameter param = AudioParameter();
558
559    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
560        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
561    }
562    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
563        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
564    }
565    if (meta->findInt32(kKeyBitRate, &bitRate)) {
566        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
567    }
568    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
569        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
570    }
571    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
572        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
573    }
574
575    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
576          "delaySample %d, paddingSample %d", bitRate, sampleRate,
577          channelMask, delaySamples, paddingSamples);
578
579    sink->setParameters(param.toString());
580    return OK;
581}
582
583struct mime_conv_t {
584    const char* mime;
585    audio_format_t format;
586};
587
588static const struct mime_conv_t mimeLookup[] = {
589    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
590    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
591    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
592    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
593    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
594    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
595    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
596    { 0, AUDIO_FORMAT_INVALID }
597};
598
599status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
600{
601const struct mime_conv_t* p = &mimeLookup[0];
602    while (p->mime != NULL) {
603        if (0 == strcasecmp(mime, p->mime)) {
604            format = p->format;
605            return OK;
606        }
607        ++p;
608    }
609
610    return BAD_VALUE;
611}
612
613struct aac_format_conv_t {
614    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
615    audio_format_t format;
616};
617
618static const struct aac_format_conv_t profileLookup[] = {
619    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
620    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
621    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
622    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
623    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
624    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
625    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
626    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
627    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
628    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
629    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
630};
631
632void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
633{
634const struct aac_format_conv_t* p = &profileLookup[0];
635    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
636        if (eAacProfile == p->eAacProfileType) {
637            format = p->format;
638            return;
639        }
640        ++p;
641    }
642    format = AUDIO_FORMAT_AAC;
643    return;
644}
645
646bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
647                      bool isStreaming, audio_stream_type_t streamType)
648{
649    const char *mime;
650    if (meta == NULL) {
651        return false;
652    }
653    CHECK(meta->findCString(kKeyMIMEType, &mime));
654
655    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
656
657    info.format = AUDIO_FORMAT_INVALID;
658    if (mapMimeToAudioFormat(info.format, mime) != OK) {
659        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
660        return false;
661    } else {
662        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
663    }
664
665    if (AUDIO_FORMAT_INVALID == info.format) {
666        // can't offload if we don't know what the source format is
667        ALOGE("mime type \"%s\" not a known audio format", mime);
668        return false;
669    }
670
671    // Redefine aac format according to its profile
672    // Offloading depends on audio DSP capabilities.
673    int32_t aacaot = -1;
674    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
675        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
676    }
677
678    int32_t srate = -1;
679    if (!meta->findInt32(kKeySampleRate, &srate)) {
680        ALOGV("track of type '%s' does not publish sample rate", mime);
681    }
682    info.sample_rate = srate;
683
684    int32_t cmask = 0;
685    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
686        ALOGV("track of type '%s' does not publish channel mask", mime);
687
688        // Try a channel count instead
689        int32_t channelCount;
690        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
691            ALOGV("track of type '%s' does not publish channel count", mime);
692        } else {
693            cmask = audio_channel_out_mask_from_count(channelCount);
694        }
695    }
696    info.channel_mask = cmask;
697
698    int64_t duration = 0;
699    if (!meta->findInt64(kKeyDuration, &duration)) {
700        ALOGV("track of type '%s' does not publish duration", mime);
701    }
702    info.duration_us = duration;
703
704    int32_t brate = -1;
705    if (!meta->findInt32(kKeyBitRate, &brate)) {
706        ALOGV("track of type '%s' does not publish bitrate", mime);
707     }
708    info.bit_rate = brate;
709
710
711    info.stream_type = streamType;
712    info.has_video = hasVideo;
713    info.is_streaming = isStreaming;
714
715    // Check if offload is possible for given format, stream type, sample rate,
716    // bit rate, duration, video and streaming
717    return AudioSystem::isOffloadSupported(info);
718}
719
720AString uriDebugString(const AString &uri, bool incognito) {
721    if (incognito) {
722        return AString("<URI suppressed>");
723    }
724
725    char prop[PROPERTY_VALUE_MAX];
726    if (property_get("media.stagefright.log-uri", prop, "false") &&
727        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
728        return uri;
729    }
730
731    // find scheme
732    AString scheme;
733    const char *chars = uri.c_str();
734    for (size_t i = 0; i < uri.size(); i++) {
735        const char c = chars[i];
736        if (!isascii(c)) {
737            break;
738        } else if (isalpha(c)) {
739            continue;
740        } else if (i == 0) {
741            // first character must be a letter
742            break;
743        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
744            continue;
745        } else if (c != ':') {
746            break;
747        }
748        scheme = AString(uri, 0, i);
749        scheme.append("://<suppressed>");
750        return scheme;
751    }
752    return AString("<no-scheme URI suppressed>");
753}
754
755}  // namespace android
756
757