Utils.cpp revision 3a474aa67fc31505740526dd249d96204c08bf79
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
113        int32_t colorFormat;
114        if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
115            msg->setInt32("color-format", colorFormat);
116        }
117
118        int32_t cropLeft, cropTop, cropRight, cropBottom;
119        if (meta->findRect(kKeyCropRect,
120                           &cropLeft,
121                           &cropTop,
122                           &cropRight,
123                           &cropBottom)) {
124            msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
125        }
126
127        int32_t rotationDegrees;
128        if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
129            msg->setInt32("rotation-degrees", rotationDegrees);
130        }
131    } else if (!strncasecmp("audio/", mime, 6)) {
132        int32_t numChannels, sampleRate;
133        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
134        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
135
136        msg->setInt32("channel-count", numChannels);
137        msg->setInt32("sample-rate", sampleRate);
138
139        int32_t channelMask;
140        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
141            msg->setInt32("channel-mask", channelMask);
142        }
143
144        int32_t delay = 0;
145        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
146            msg->setInt32("encoder-delay", delay);
147        }
148        int32_t padding = 0;
149        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
150            msg->setInt32("encoder-padding", padding);
151        }
152
153        int32_t isADTS;
154        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
155            msg->setInt32("is-adts", true);
156        }
157
158        int32_t aacProfile = -1;
159        if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
160            msg->setInt32("aac-profile", aacProfile);
161        }
162    }
163
164    int32_t maxInputSize;
165    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
166        msg->setInt32("max-input-size", maxInputSize);
167    }
168
169    int32_t maxWidth;
170    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
171        msg->setInt32("max-width", maxWidth);
172    }
173
174    int32_t maxHeight;
175    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
176        msg->setInt32("max-height", maxHeight);
177    }
178
179    int32_t rotationDegrees;
180    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
181        msg->setInt32("rotation-degrees", rotationDegrees);
182    }
183
184    int32_t fps;
185    if (meta->findInt32(kKeyFrameRate, &fps)) {
186        msg->setInt32("frame-rate", fps);
187    }
188
189    uint32_t type;
190    const void *data;
191    size_t size;
192    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
193        // Parse the AVCDecoderConfigurationRecord
194
195        const uint8_t *ptr = (const uint8_t *)data;
196
197        CHECK(size >= 7);
198        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
199        uint8_t profile __unused = ptr[1];
200        uint8_t level __unused = ptr[3];
201
202        // There is decodable content out there that fails the following
203        // assertion, let's be lenient for now...
204        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
205
206        size_t lengthSize __unused = 1 + (ptr[4] & 3);
207
208        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
209        // violates it...
210        // CHECK((ptr[5] >> 5) == 7);  // reserved
211
212        size_t numSeqParameterSets = ptr[5] & 31;
213
214        ptr += 6;
215        size -= 6;
216
217        sp<ABuffer> buffer = new ABuffer(1024);
218        buffer->setRange(0, 0);
219
220        for (size_t i = 0; i < numSeqParameterSets; ++i) {
221            CHECK(size >= 2);
222            size_t length = U16_AT(ptr);
223
224            ptr += 2;
225            size -= 2;
226
227            CHECK(size >= length);
228
229            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
230            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
231            buffer->setRange(0, buffer->size() + 4 + length);
232
233            ptr += length;
234            size -= length;
235        }
236
237        buffer->meta()->setInt32("csd", true);
238        buffer->meta()->setInt64("timeUs", 0);
239
240        msg->setBuffer("csd-0", buffer);
241
242        buffer = new ABuffer(1024);
243        buffer->setRange(0, 0);
244
245        CHECK(size >= 1);
246        size_t numPictureParameterSets = *ptr;
247        ++ptr;
248        --size;
249
250        for (size_t i = 0; i < numPictureParameterSets; ++i) {
251            CHECK(size >= 2);
252            size_t length = U16_AT(ptr);
253
254            ptr += 2;
255            size -= 2;
256
257            CHECK(size >= length);
258
259            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
260            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
261            buffer->setRange(0, buffer->size() + 4 + length);
262
263            ptr += length;
264            size -= length;
265        }
266
267        buffer->meta()->setInt32("csd", true);
268        buffer->meta()->setInt64("timeUs", 0);
269        msg->setBuffer("csd-1", buffer);
270    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
271        const uint8_t *ptr = (const uint8_t *)data;
272
273        CHECK(size >= 7);
274        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
275        uint8_t profile __unused = ptr[1] & 31;
276        uint8_t level __unused = ptr[12];
277        ptr += 22;
278        size -= 22;
279
280
281        size_t numofArrays = (char)ptr[0];
282        ptr += 1;
283        size -= 1;
284        size_t j = 0, i = 0;
285
286        sp<ABuffer> buffer = new ABuffer(1024);
287        buffer->setRange(0, 0);
288
289        for (i = 0; i < numofArrays; i++) {
290            ptr += 1;
291            size -= 1;
292
293            //Num of nals
294            size_t numofNals = U16_AT(ptr);
295
296            ptr += 2;
297            size -= 2;
298
299            for (j = 0; j < numofNals; j++) {
300                CHECK(size >= 2);
301                size_t length = U16_AT(ptr);
302
303                ptr += 2;
304                size -= 2;
305
306                CHECK(size >= length);
307
308                memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
309                memcpy(buffer->data() + buffer->size() + 4, ptr, length);
310                buffer->setRange(0, buffer->size() + 4 + length);
311
312                ptr += length;
313                size -= length;
314            }
315        }
316        buffer->meta()->setInt32("csd", true);
317        buffer->meta()->setInt64("timeUs", 0);
318        msg->setBuffer("csd-0", buffer);
319
320    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
321        ESDS esds((const char *)data, size);
322        CHECK_EQ(esds.InitCheck(), (status_t)OK);
323
324        const void *codec_specific_data;
325        size_t codec_specific_data_size;
326        esds.getCodecSpecificInfo(
327                &codec_specific_data, &codec_specific_data_size);
328
329        sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
330
331        memcpy(buffer->data(), codec_specific_data,
332               codec_specific_data_size);
333
334        buffer->meta()->setInt32("csd", true);
335        buffer->meta()->setInt64("timeUs", 0);
336        msg->setBuffer("csd-0", buffer);
337    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
338        sp<ABuffer> buffer = new ABuffer(size);
339        memcpy(buffer->data(), data, size);
340
341        buffer->meta()->setInt32("csd", true);
342        buffer->meta()->setInt64("timeUs", 0);
343        msg->setBuffer("csd-0", buffer);
344
345        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
346            return -EINVAL;
347        }
348
349        buffer = new ABuffer(size);
350        memcpy(buffer->data(), data, size);
351
352        buffer->meta()->setInt32("csd", true);
353        buffer->meta()->setInt64("timeUs", 0);
354        msg->setBuffer("csd-1", buffer);
355    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
356        sp<ABuffer> buffer = new ABuffer(size);
357        memcpy(buffer->data(), data, size);
358
359        buffer->meta()->setInt32("csd", true);
360        buffer->meta()->setInt64("timeUs", 0);
361        msg->setBuffer("csd-0", buffer);
362
363        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
364            return -EINVAL;
365        }
366
367        buffer = new ABuffer(size);
368        memcpy(buffer->data(), data, size);
369
370        buffer->meta()->setInt32("csd", true);
371        buffer->meta()->setInt64("timeUs", 0);
372        msg->setBuffer("csd-1", buffer);
373
374        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
375            return -EINVAL;
376        }
377
378        buffer = new ABuffer(size);
379        memcpy(buffer->data(), data, size);
380
381        buffer->meta()->setInt32("csd", true);
382        buffer->meta()->setInt64("timeUs", 0);
383        msg->setBuffer("csd-2", buffer);
384    }
385
386    *format = msg;
387
388    return OK;
389}
390
391static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
392
393    avcc[0] = 1;        // version
394    avcc[1] = 0x64;     // profile
395    avcc[2] = 0;        // unused (?)
396    avcc[3] = 0xd;      // level
397    avcc[4] = 0xff;     // reserved+size
398
399    size_t i = 0;
400    int numparams = 0;
401    int lastparamoffset = 0;
402    int avccidx = 6;
403    do {
404        if (i >= csd0->size() - 4 ||
405                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
406            if (i >= csd0->size() - 4) {
407                // there can't be another param here, so use all the rest
408                i = csd0->size();
409            }
410            ALOGV("block at %zu, last was %d", i, lastparamoffset);
411            if (lastparamoffset > 0) {
412                int size = i - lastparamoffset;
413                avcc[avccidx++] = size >> 8;
414                avcc[avccidx++] = size & 0xff;
415                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
416                avccidx += size;
417                numparams++;
418            }
419            i += 4;
420            lastparamoffset = i;
421        } else {
422            i++;
423        }
424    } while(i < csd0->size());
425    ALOGV("csd0 contains %d params", numparams);
426
427    avcc[5] = 0xe0 | numparams;
428    //and now csd-1
429    i = 0;
430    numparams = 0;
431    lastparamoffset = 0;
432    int numpicparamsoffset = avccidx;
433    avccidx++;
434    do {
435        if (i >= csd1->size() - 4 ||
436                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
437            if (i >= csd1->size() - 4) {
438                // there can't be another param here, so use all the rest
439                i = csd1->size();
440            }
441            ALOGV("block at %zu, last was %d", i, lastparamoffset);
442            if (lastparamoffset > 0) {
443                int size = i - lastparamoffset;
444                avcc[avccidx++] = size >> 8;
445                avcc[avccidx++] = size & 0xff;
446                memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
447                avccidx += size;
448                numparams++;
449            }
450            i += 4;
451            lastparamoffset = i;
452        } else {
453            i++;
454        }
455    } while(i < csd1->size());
456    avcc[numpicparamsoffset] = numparams;
457    return avccidx;
458}
459
460static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
461    int csd0size = csd0->size();
462    esds[0] = 3; // kTag_ESDescriptor;
463    int esdescriptorsize = 26 + csd0size;
464    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
465    esds[1] = 0x80 | (esdescriptorsize >> 21);
466    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
467    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
468    esds[4] = (esdescriptorsize & 0x7f);
469    esds[5] = esds[6] = 0; // es id
470    esds[7] = 0; // flags
471    esds[8] = 4; // kTag_DecoderConfigDescriptor
472    int configdescriptorsize = 18 + csd0size;
473    esds[9] = 0x80 | (configdescriptorsize >> 21);
474    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
475    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
476    esds[12] = (configdescriptorsize & 0x7f);
477    esds[13] = 0x40; // objectTypeIndication
478    esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
479    esds[15] = 0x00; // but the actual values here were taken from a real file.
480    esds[16] = 0x18;
481    esds[17] = 0x00;
482    esds[18] = 0x00;
483    esds[19] = 0x00;
484    esds[20] = 0xfa;
485    esds[21] = 0x00;
486    esds[22] = 0x00;
487    esds[23] = 0x00;
488    esds[24] = 0xfa;
489    esds[25] = 0x00;
490    esds[26] = 5; // kTag_DecoderSpecificInfo;
491    esds[27] = 0x80 | (csd0size >> 21);
492    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
493    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
494    esds[30] = (csd0size & 0x7f);
495    memcpy((void*)&esds[31], csd0->data(), csd0size);
496    // data following this is ignored, so don't bother appending it
497
498}
499
500void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
501    AString mime;
502    if (msg->findString("mime", &mime)) {
503        meta->setCString(kKeyMIMEType, mime.c_str());
504    } else {
505        ALOGW("did not find mime type");
506    }
507
508    int64_t durationUs;
509    if (msg->findInt64("durationUs", &durationUs)) {
510        meta->setInt64(kKeyDuration, durationUs);
511    }
512
513    int32_t isSync;
514    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
515        meta->setInt32(kKeyIsSyncFrame, 1);
516    }
517
518    if (mime.startsWith("video/")) {
519        int32_t width;
520        int32_t height;
521        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
522            meta->setInt32(kKeyWidth, width);
523            meta->setInt32(kKeyHeight, height);
524        } else {
525            ALOGW("did not find width and/or height");
526        }
527
528        int32_t sarWidth, sarHeight;
529        if (msg->findInt32("sar-width", &sarWidth)
530                && msg->findInt32("sar-height", &sarHeight)) {
531            meta->setInt32(kKeySARWidth, sarWidth);
532            meta->setInt32(kKeySARHeight, sarHeight);
533        }
534
535        int32_t colorFormat;
536        if (msg->findInt32("color-format", &colorFormat)) {
537            meta->setInt32(kKeyColorFormat, colorFormat);
538        }
539
540        int32_t cropLeft, cropTop, cropRight, cropBottom;
541        if (msg->findRect("crop",
542                          &cropLeft,
543                          &cropTop,
544                          &cropRight,
545                          &cropBottom)) {
546            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
547        }
548
549        int32_t rotationDegrees;
550        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
551            meta->setInt32(kKeyRotation, rotationDegrees);
552        }
553    } else if (mime.startsWith("audio/")) {
554        int32_t numChannels;
555        if (msg->findInt32("channel-count", &numChannels)) {
556            meta->setInt32(kKeyChannelCount, numChannels);
557        }
558        int32_t sampleRate;
559        if (msg->findInt32("sample-rate", &sampleRate)) {
560            meta->setInt32(kKeySampleRate, sampleRate);
561        }
562        int32_t channelMask;
563        if (msg->findInt32("channel-mask", &channelMask)) {
564            meta->setInt32(kKeyChannelMask, channelMask);
565        }
566        int32_t delay = 0;
567        if (msg->findInt32("encoder-delay", &delay)) {
568            meta->setInt32(kKeyEncoderDelay, delay);
569        }
570        int32_t padding = 0;
571        if (msg->findInt32("encoder-padding", &padding)) {
572            meta->setInt32(kKeyEncoderPadding, padding);
573        }
574
575        int32_t isADTS;
576        if (msg->findInt32("is-adts", &isADTS)) {
577            meta->setInt32(kKeyIsADTS, isADTS);
578        }
579    }
580
581    int32_t maxInputSize;
582    if (msg->findInt32("max-input-size", &maxInputSize)) {
583        meta->setInt32(kKeyMaxInputSize, maxInputSize);
584    }
585
586    int32_t maxWidth;
587    if (msg->findInt32("max-width", &maxWidth)) {
588        meta->setInt32(kKeyMaxWidth, maxWidth);
589    }
590
591    int32_t maxHeight;
592    if (msg->findInt32("max-height", &maxHeight)) {
593        meta->setInt32(kKeyMaxHeight, maxHeight);
594    }
595
596    int32_t fps;
597    if (msg->findInt32("frame-rate", &fps)) {
598        meta->setInt32(kKeyFrameRate, fps);
599    }
600
601    // reassemble the csd data into its original form
602    sp<ABuffer> csd0;
603    if (msg->findBuffer("csd-0", &csd0)) {
604        if (mime.startsWith("video/")) { // do we need to be stricter than this?
605            sp<ABuffer> csd1;
606            if (msg->findBuffer("csd-1", &csd1)) {
607                char avcc[1024]; // that oughta be enough, right?
608                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
609                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
610            }
611        } else if (mime.startsWith("audio/")) {
612            int csd0size = csd0->size();
613            char esds[csd0size + 31];
614            reassembleESDS(csd0, esds);
615            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
616        }
617    }
618
619    int32_t timeScale;
620    if (msg->findInt32("time-scale", &timeScale)) {
621        meta->setInt32(kKeyTimeScale, timeScale);
622    }
623
624    // XXX TODO add whatever other keys there are
625
626#if 0
627    ALOGI("converted %s to:", msg->debugString(0).c_str());
628    meta->dumpToLog();
629#endif
630}
631
632AString MakeUserAgent() {
633    AString ua;
634    ua.append("stagefright/1.2 (Linux;Android ");
635
636#if (PROPERTY_VALUE_MAX < 8)
637#error "PROPERTY_VALUE_MAX must be at least 8"
638#endif
639
640    char value[PROPERTY_VALUE_MAX];
641    property_get("ro.build.version.release", value, "Unknown");
642    ua.append(value);
643    ua.append(")");
644
645    return ua;
646}
647
648status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
649                           const sp<MetaData>& meta)
650{
651    int32_t sampleRate = 0;
652    int32_t bitRate = 0;
653    int32_t channelMask = 0;
654    int32_t delaySamples = 0;
655    int32_t paddingSamples = 0;
656
657    AudioParameter param = AudioParameter();
658
659    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
660        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
661    }
662    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
663        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
664    }
665    if (meta->findInt32(kKeyBitRate, &bitRate)) {
666        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
667    }
668    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
669        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
670    }
671    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
672        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
673    }
674
675    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
676          "delaySample %d, paddingSample %d", bitRate, sampleRate,
677          channelMask, delaySamples, paddingSamples);
678
679    sink->setParameters(param.toString());
680    return OK;
681}
682
683struct mime_conv_t {
684    const char* mime;
685    audio_format_t format;
686};
687
688static const struct mime_conv_t mimeLookup[] = {
689    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
690    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
691    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
692    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
693    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
694    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
695    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
696    { 0, AUDIO_FORMAT_INVALID }
697};
698
699status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
700{
701const struct mime_conv_t* p = &mimeLookup[0];
702    while (p->mime != NULL) {
703        if (0 == strcasecmp(mime, p->mime)) {
704            format = p->format;
705            return OK;
706        }
707        ++p;
708    }
709
710    return BAD_VALUE;
711}
712
713struct aac_format_conv_t {
714    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
715    audio_format_t format;
716};
717
718static const struct aac_format_conv_t profileLookup[] = {
719    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
720    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
721    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
722    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
723    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
724    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
725    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
726    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
727    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
728    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
729    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
730};
731
732void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
733{
734const struct aac_format_conv_t* p = &profileLookup[0];
735    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
736        if (eAacProfile == p->eAacProfileType) {
737            format = p->format;
738            return;
739        }
740        ++p;
741    }
742    format = AUDIO_FORMAT_AAC;
743    return;
744}
745
746bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
747                      bool isStreaming, audio_stream_type_t streamType)
748{
749    const char *mime;
750    if (meta == NULL) {
751        return false;
752    }
753    CHECK(meta->findCString(kKeyMIMEType, &mime));
754
755    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
756
757    info.format = AUDIO_FORMAT_INVALID;
758    if (mapMimeToAudioFormat(info.format, mime) != OK) {
759        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
760        return false;
761    } else {
762        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
763    }
764
765    if (AUDIO_FORMAT_INVALID == info.format) {
766        // can't offload if we don't know what the source format is
767        ALOGE("mime type \"%s\" not a known audio format", mime);
768        return false;
769    }
770
771    // Redefine aac format according to its profile
772    // Offloading depends on audio DSP capabilities.
773    int32_t aacaot = -1;
774    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
775        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
776    }
777
778    int32_t srate = -1;
779    if (!meta->findInt32(kKeySampleRate, &srate)) {
780        ALOGV("track of type '%s' does not publish sample rate", mime);
781    }
782    info.sample_rate = srate;
783
784    int32_t cmask = 0;
785    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
786        ALOGV("track of type '%s' does not publish channel mask", mime);
787
788        // Try a channel count instead
789        int32_t channelCount;
790        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
791            ALOGV("track of type '%s' does not publish channel count", mime);
792        } else {
793            cmask = audio_channel_out_mask_from_count(channelCount);
794        }
795    }
796    info.channel_mask = cmask;
797
798    int64_t duration = 0;
799    if (!meta->findInt64(kKeyDuration, &duration)) {
800        ALOGV("track of type '%s' does not publish duration", mime);
801    }
802    info.duration_us = duration;
803
804    int32_t brate = -1;
805    if (!meta->findInt32(kKeyBitRate, &brate)) {
806        ALOGV("track of type '%s' does not publish bitrate", mime);
807     }
808    info.bit_rate = brate;
809
810
811    info.stream_type = streamType;
812    info.has_video = hasVideo;
813    info.is_streaming = isStreaming;
814
815    // Check if offload is possible for given format, stream type, sample rate,
816    // bit rate, duration, video and streaming
817    return AudioSystem::isOffloadSupported(info);
818}
819
820AString uriDebugString(const AString &uri, bool incognito) {
821    if (incognito) {
822        return AString("<URI suppressed>");
823    }
824
825    char prop[PROPERTY_VALUE_MAX];
826    if (property_get("media.stagefright.log-uri", prop, "false") &&
827        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
828        return uri;
829    }
830
831    // find scheme
832    AString scheme;
833    const char *chars = uri.c_str();
834    for (size_t i = 0; i < uri.size(); i++) {
835        const char c = chars[i];
836        if (!isascii(c)) {
837            break;
838        } else if (isalpha(c)) {
839            continue;
840        } else if (i == 0) {
841            // first character must be a letter
842            break;
843        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
844            continue;
845        } else if (c != ':') {
846            break;
847        }
848        scheme = AString(uri, 0, i);
849        scheme.append("://<suppressed>");
850        return scheme;
851    }
852    return AString("<no-scheme URI suppressed>");
853}
854
855HLSTime::HLSTime(const sp<AMessage>& meta) :
856    mSeq(-1),
857    mTimeUs(-1ll),
858    mMeta(meta) {
859    if (meta != NULL) {
860        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
861        CHECK(meta->findInt64("timeUs", &mTimeUs));
862    }
863}
864
865int64_t HLSTime::getSegmentTimeUs() const {
866    int64_t segmentStartTimeUs = -1ll;
867    if (mMeta != NULL) {
868        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
869
870        int64_t segmentFirstTimeUs;
871        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
872            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
873        }
874
875        // adjust segment time by playlist age (for live streaming)
876        int64_t playlistTimeUs;
877        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
878            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
879
880            int64_t durationUs;
881            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
882
883            // round to nearest whole segment
884            playlistAgeUs = (playlistAgeUs + durationUs / 2)
885                    / durationUs * durationUs;
886
887            segmentStartTimeUs -= playlistAgeUs;
888            if (segmentStartTimeUs < 0) {
889                segmentStartTimeUs = 0;
890            }
891        }
892    }
893    return segmentStartTimeUs;
894}
895
896bool operator <(const HLSTime &t0, const HLSTime &t1) {
897    // we can only compare discontinuity sequence and timestamp.
898    // (mSegmentTimeUs is not reliable in live streaming case, it's the
899    // time starting from beginning of playlist but playlist could change.)
900    return t0.mSeq < t1.mSeq
901            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
902}
903
904void writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
905    msg->setFloat("speed", rate.mSpeed);
906    msg->setFloat("pitch", rate.mPitch);
907    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
908    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
909}
910
911void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
912    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
913    CHECK(msg->findFloat("speed", &rate->mSpeed));
914    CHECK(msg->findFloat("pitch", &rate->mPitch));
915    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
916    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
917}
918
919void writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
920    msg->setInt32("sync-source", sync.mSource);
921    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
922    msg->setFloat("tolerance", sync.mTolerance);
923    msg->setFloat("video-fps", videoFpsHint);
924}
925
926void readFromAMessage(
927        const sp<AMessage> &msg,
928        AVSyncSettings *sync /* nonnull */,
929        float *videoFps /* nonnull */) {
930    AVSyncSettings settings;
931    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
932    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
933    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
934    CHECK(msg->findFloat("video-fps", videoFps));
935    *sync = settings;
936}
937
938}  // namespace android
939
940