17dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang/*
27dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * Copyright 2018 The Android Open Source Project
37dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang *
47dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * Licensed under the Apache License, Version 2.0 (the "License");
57dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * you may not use this file except in compliance with the License.
67dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * You may obtain a copy of the License at
77dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang *
87dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang *      http://www.apache.org/licenses/LICENSE-2.0
97dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang *
107dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * Unless required by applicable law or agreed to in writing, software
117dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * distributed under the License is distributed on an "AS IS" BASIS,
127dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * See the License for the specific language governing permissions and
147dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang * limitations under the License.
157dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang */
167dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
177dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang//#define LOG_NDEBUG 0
187dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#define LOG_TAG "MetaDataUtils"
197dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
207dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#include <media/stagefright/foundation/avc_utils.h>
217dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#include <media/stagefright/foundation/ABuffer.h>
227dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#include <media/stagefright/MediaDefs.h>
237dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang#include <media/stagefright/MetaDataUtils.h>
247dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
257dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kangnamespace android {
267dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
27a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissenbool MakeAVCCodecSpecificData(MetaDataBase &meta, const uint8_t *data, size_t size) {
287dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    int32_t width;
297dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    int32_t height;
307dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    int32_t sarWidth;
317dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    int32_t sarHeight;
32a1a005fc01118685c92e723c8dcf7afeffc9d59cMarco Nelissen    sp<ABuffer> accessUnit = new ABuffer((void*)data,  size);
337dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    sp<ABuffer> csd = MakeAVCCodecSpecificData(accessUnit, &width, &height, &sarWidth, &sarHeight);
347dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    if (csd == nullptr) {
353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
367dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    }
373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
387dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setInt32(kKeyWidth, width);
413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setInt32(kKeyHeight, height);
427dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    if (sarWidth > 0 && sarHeight > 0) {
433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        meta.setInt32(kKeySARWidth, sarWidth);
443d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        meta.setInt32(kKeySARHeight, sarHeight);
457dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    }
463d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
477dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang}
487dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
493d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MakeAACCodecSpecificData(
503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        MetaDataBase &meta,
517dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang        unsigned profile, unsigned sampling_freq_index,
527dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang        unsigned channel_configuration) {
53fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    if(sampling_freq_index > 11u) {
543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
557dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang    }
56fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    int32_t sampleRate;
57fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    int32_t channelCount;
58fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    static const int32_t kSamplingFreq[] = {
59fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
60fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        16000, 12000, 11025, 8000
61fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    };
62fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    sampleRate = kSamplingFreq[sampling_freq_index];
63fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    channelCount = channel_configuration;
64fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
65fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    static const uint8_t kStaticESDS[] = {
66fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x03, 22,
67fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x00, 0x00,     // ES_ID
68fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
69fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
70fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x04, 17,
71fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x40,                       // Audio ISO/IEC 14496-3
72fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x00, 0x00, 0x00, 0x00,
73fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x00, 0x00, 0x00, 0x00,
74fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x00, 0x00, 0x00, 0x00,
75fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
76fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        0x05, 2,
77fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        // AudioSpecificInfo follows
78fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
79fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        // oooo offf fccc c000
80fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        // o - audioObjectType
81fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        // f - samplingFreqIndex
82fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        // c - channelConfig
83fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    };
84fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
85fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    size_t csdSize = sizeof(kStaticESDS) + 2;
86fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    uint8_t *csd = new uint8_t[csdSize];
87fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    memcpy(csd, kStaticESDS, sizeof(kStaticESDS));
88fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
89fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    csd[sizeof(kStaticESDS)] =
90fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        ((profile + 1) << 3) | (sampling_freq_index >> 1);
91fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
92fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    csd[sizeof(kStaticESDS) + 1] =
93fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen        ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
94fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen
953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
967dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
973d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setInt32(kKeySampleRate, sampleRate);
983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setInt32(kKeyChannelCount, channelCount);
997dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
1003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    meta.setData(kKeyESDS, 0, csd, csdSize);
101fca6559a72ee52648133ea5220be85960a3560e0Marco Nelissen    delete [] csd;
1023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
1037dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang}
1047dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang
1057dc218e17800cc3ac95551e3280820f407adf7b5Dongwon Kang}  // namespace android
106