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