1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/*
2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License.
6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at
7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and
14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License.
15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */
16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
17cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPAssembler.h"
18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
21af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber#include <media/stagefright/foundation/ALooper.h>
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <stdint.h>
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPAssembler::ARTPAssembler()
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    : mFirstFailureTimeUs(-1) {
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPAssembler::onPacketReceived(const sp<ARTPSource> &source) {
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AssemblyStatus status;
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (;;) {
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        status = assembleMore(source);
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (status == WRONG_SEQUENCE_NUMBER) {
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (mFirstFailureTimeUs >= 0) {
39af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber                if (ALooper::GetNowUs() - mFirstFailureTimeUs > 10000ll) {
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    mFirstFailureTimeUs = -1;
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    // LOG(VERBOSE) << "waited too long for packet.";
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    packetLost();
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    continue;
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            } else {
47af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber                mFirstFailureTimeUs = ALooper::GetNowUs();
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else {
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            mFirstFailureTimeUs = -1;
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (status == NOT_ENOUGH_DATA) {
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
608d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber// static
618d342970108926c4ea355c90d26a2a353ec0fd47Andreas Hubervoid ARTPAssembler::CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from) {
628d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    uint32_t rtpTime;
638d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CHECK(from->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
648d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
658d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    to->meta()->setInt32("rtp-time", rtpTime);
668d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
678d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    // Copy the seq number.
688d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    to->setInt32Data(from->int32Data());
698d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber}
708d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber
718647bbe4420ca487467318404127f52c567e346bAndreas Huber// static
728647bbe4420ca487467318404127f52c567e346bAndreas Hubersp<ABuffer> ARTPAssembler::MakeADTSCompoundFromAACFrames(
738647bbe4420ca487467318404127f52c567e346bAndreas Huber        unsigned profile,
748647bbe4420ca487467318404127f52c567e346bAndreas Huber        unsigned samplingFreqIndex,
758647bbe4420ca487467318404127f52c567e346bAndreas Huber        unsigned channelConfig,
768647bbe4420ca487467318404127f52c567e346bAndreas Huber        const List<sp<ABuffer> > &frames) {
778647bbe4420ca487467318404127f52c567e346bAndreas Huber    size_t totalSize = 0;
788647bbe4420ca487467318404127f52c567e346bAndreas Huber    for (List<sp<ABuffer> >::const_iterator it = frames.begin();
798647bbe4420ca487467318404127f52c567e346bAndreas Huber         it != frames.end(); ++it) {
808647bbe4420ca487467318404127f52c567e346bAndreas Huber        // Each frame is prefixed by a 7 byte ADTS header
818647bbe4420ca487467318404127f52c567e346bAndreas Huber        totalSize += (*it)->size() + 7;
828647bbe4420ca487467318404127f52c567e346bAndreas Huber    }
838647bbe4420ca487467318404127f52c567e346bAndreas Huber
848647bbe4420ca487467318404127f52c567e346bAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(totalSize);
858647bbe4420ca487467318404127f52c567e346bAndreas Huber    size_t offset = 0;
868647bbe4420ca487467318404127f52c567e346bAndreas Huber    for (List<sp<ABuffer> >::const_iterator it = frames.begin();
878647bbe4420ca487467318404127f52c567e346bAndreas Huber         it != frames.end(); ++it) {
888647bbe4420ca487467318404127f52c567e346bAndreas Huber        sp<ABuffer> nal = *it;
898647bbe4420ca487467318404127f52c567e346bAndreas Huber        uint8_t *dst = accessUnit->data() + offset;
908647bbe4420ca487467318404127f52c567e346bAndreas Huber
918647bbe4420ca487467318404127f52c567e346bAndreas Huber        static const unsigned kADTSId = 0;
928647bbe4420ca487467318404127f52c567e346bAndreas Huber        static const unsigned kADTSLayer = 0;
938647bbe4420ca487467318404127f52c567e346bAndreas Huber        static const unsigned kADTSProtectionAbsent = 1;
948647bbe4420ca487467318404127f52c567e346bAndreas Huber
958647bbe4420ca487467318404127f52c567e346bAndreas Huber        unsigned frameLength = nal->size() + 7;
968647bbe4420ca487467318404127f52c567e346bAndreas Huber
978647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[0] = 0xff;
988647bbe4420ca487467318404127f52c567e346bAndreas Huber
998647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[1] =
1008647bbe4420ca487467318404127f52c567e346bAndreas Huber            0xf0 | (kADTSId << 3) | (kADTSLayer << 1) | kADTSProtectionAbsent;
1018647bbe4420ca487467318404127f52c567e346bAndreas Huber
1028647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[2] = (profile << 6)
1038647bbe4420ca487467318404127f52c567e346bAndreas Huber                | (samplingFreqIndex << 2)
1048647bbe4420ca487467318404127f52c567e346bAndreas Huber                | (channelConfig >> 2);
1058647bbe4420ca487467318404127f52c567e346bAndreas Huber
1068647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[3] = ((channelConfig & 3) << 6) | (frameLength >> 11);
1078647bbe4420ca487467318404127f52c567e346bAndreas Huber
1088647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[4] = (frameLength >> 3) & 0xff;
1098647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[5] = (frameLength & 7) << 5;
1108647bbe4420ca487467318404127f52c567e346bAndreas Huber        dst[6] = 0x00;
1118647bbe4420ca487467318404127f52c567e346bAndreas Huber
1128647bbe4420ca487467318404127f52c567e346bAndreas Huber        memcpy(dst + 7, nal->data(), nal->size());
1138647bbe4420ca487467318404127f52c567e346bAndreas Huber        offset += nal->size() + 7;
1148647bbe4420ca487467318404127f52c567e346bAndreas Huber    }
1158647bbe4420ca487467318404127f52c567e346bAndreas Huber
1168647bbe4420ca487467318404127f52c567e346bAndreas Huber    CopyTimes(accessUnit, *frames.begin());
1178647bbe4420ca487467318404127f52c567e346bAndreas Huber
1188647bbe4420ca487467318404127f52c567e346bAndreas Huber    return accessUnit;
1198647bbe4420ca487467318404127f52c567e346bAndreas Huber}
1208647bbe4420ca487467318404127f52c567e346bAndreas Huber
1218647bbe4420ca487467318404127f52c567e346bAndreas Huber// static
1228647bbe4420ca487467318404127f52c567e346bAndreas Hubersp<ABuffer> ARTPAssembler::MakeCompoundFromPackets(
1238647bbe4420ca487467318404127f52c567e346bAndreas Huber        const List<sp<ABuffer> > &packets) {
1248647bbe4420ca487467318404127f52c567e346bAndreas Huber    size_t totalSize = 0;
1258647bbe4420ca487467318404127f52c567e346bAndreas Huber    for (List<sp<ABuffer> >::const_iterator it = packets.begin();
1268647bbe4420ca487467318404127f52c567e346bAndreas Huber         it != packets.end(); ++it) {
1278647bbe4420ca487467318404127f52c567e346bAndreas Huber        totalSize += (*it)->size();
1288647bbe4420ca487467318404127f52c567e346bAndreas Huber    }
1298647bbe4420ca487467318404127f52c567e346bAndreas Huber
1308647bbe4420ca487467318404127f52c567e346bAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(totalSize);
1318647bbe4420ca487467318404127f52c567e346bAndreas Huber    size_t offset = 0;
1328647bbe4420ca487467318404127f52c567e346bAndreas Huber    for (List<sp<ABuffer> >::const_iterator it = packets.begin();
1338647bbe4420ca487467318404127f52c567e346bAndreas Huber         it != packets.end(); ++it) {
1348647bbe4420ca487467318404127f52c567e346bAndreas Huber        sp<ABuffer> nal = *it;
1358647bbe4420ca487467318404127f52c567e346bAndreas Huber        memcpy(accessUnit->data() + offset, nal->data(), nal->size());
1368647bbe4420ca487467318404127f52c567e346bAndreas Huber        offset += nal->size();
1378647bbe4420ca487467318404127f52c567e346bAndreas Huber    }
1388647bbe4420ca487467318404127f52c567e346bAndreas Huber
1398647bbe4420ca487467318404127f52c567e346bAndreas Huber    CopyTimes(accessUnit, *packets.begin());
1408647bbe4420ca487467318404127f52c567e346bAndreas Huber
1418647bbe4420ca487467318404127f52c567e346bAndreas Huber    return accessUnit;
1428647bbe4420ca487467318404127f52c567e346bAndreas Huber}
1438647bbe4420ca487467318404127f52c567e346bAndreas Huber
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
145