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