1 /*
2  * Copyright (C) 2010 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 #include "ARTPAssembler.h"
18 
19 #include <media/stagefright/foundation/ABuffer.h>
20 #include <media/stagefright/foundation/ADebug.h>
21 #include <media/stagefright/foundation/ALooper.h>
22 #include <media/stagefright/foundation/AMessage.h>
23 
24 #include <stdint.h>
25 
26 namespace android {
27 
ARTPAssembler()28 ARTPAssembler::ARTPAssembler()
29     : mFirstFailureTimeUs(-1) {
30 }
31 
onPacketReceived(const sp<ARTPSource> & source)32 void ARTPAssembler::onPacketReceived(const sp<ARTPSource> &source) {
33     AssemblyStatus status;
34     for (;;) {
35         status = assembleMore(source);
36 
37         if (status == WRONG_SEQUENCE_NUMBER) {
38             if (mFirstFailureTimeUs >= 0) {
39                 if (ALooper::GetNowUs() - mFirstFailureTimeUs > 10000LL) {
40                     mFirstFailureTimeUs = -1;
41 
42                     // LOG(VERBOSE) << "waited too long for packet.";
43                     packetLost();
44                     continue;
45                 }
46             } else {
47                 mFirstFailureTimeUs = ALooper::GetNowUs();
48             }
49             break;
50         } else {
51             mFirstFailureTimeUs = -1;
52 
53             if (status == NOT_ENOUGH_DATA) {
54                 break;
55             }
56         }
57     }
58 }
59 
60 // static
CopyTimes(const sp<ABuffer> & to,const sp<ABuffer> & from)61 void ARTPAssembler::CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from) {
62     uint32_t rtpTime;
63     CHECK(from->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
64 
65     to->meta()->setInt32("rtp-time", rtpTime);
66 
67     // Copy the seq number.
68     to->setInt32Data(from->int32Data());
69 }
70 
71 // static
MakeADTSCompoundFromAACFrames(unsigned profile,unsigned samplingFreqIndex,unsigned channelConfig,const List<sp<ABuffer>> & frames)72 sp<ABuffer> ARTPAssembler::MakeADTSCompoundFromAACFrames(
73         unsigned profile,
74         unsigned samplingFreqIndex,
75         unsigned channelConfig,
76         const List<sp<ABuffer> > &frames) {
77     size_t totalSize = 0;
78     for (List<sp<ABuffer> >::const_iterator it = frames.begin();
79          it != frames.end(); ++it) {
80         // Each frame is prefixed by a 7 byte ADTS header
81         totalSize += (*it)->size() + 7;
82     }
83 
84     sp<ABuffer> accessUnit = new ABuffer(totalSize);
85     size_t offset = 0;
86     for (List<sp<ABuffer> >::const_iterator it = frames.begin();
87          it != frames.end(); ++it) {
88         sp<ABuffer> nal = *it;
89         uint8_t *dst = accessUnit->data() + offset;
90 
91         static const unsigned kADTSId = 0;
92         static const unsigned kADTSLayer = 0;
93         static const unsigned kADTSProtectionAbsent = 1;
94 
95         unsigned frameLength = nal->size() + 7;
96 
97         dst[0] = 0xff;
98 
99         dst[1] =
100             0xf0 | (kADTSId << 3) | (kADTSLayer << 1) | kADTSProtectionAbsent;
101 
102         dst[2] = (profile << 6)
103                 | (samplingFreqIndex << 2)
104                 | (channelConfig >> 2);
105 
106         dst[3] = ((channelConfig & 3) << 6) | (frameLength >> 11);
107 
108         dst[4] = (frameLength >> 3) & 0xff;
109         dst[5] = (frameLength & 7) << 5;
110         dst[6] = 0x00;
111 
112         memcpy(dst + 7, nal->data(), nal->size());
113         offset += nal->size() + 7;
114     }
115 
116     CopyTimes(accessUnit, *frames.begin());
117 
118     return accessUnit;
119 }
120 
121 // static
MakeCompoundFromPackets(const List<sp<ABuffer>> & packets)122 sp<ABuffer> ARTPAssembler::MakeCompoundFromPackets(
123         const List<sp<ABuffer> > &packets) {
124     size_t totalSize = 0;
125     for (List<sp<ABuffer> >::const_iterator it = packets.begin();
126          it != packets.end(); ++it) {
127         totalSize += (*it)->size();
128     }
129 
130     sp<ABuffer> accessUnit = new ABuffer(totalSize);
131     size_t offset = 0;
132     for (List<sp<ABuffer> >::const_iterator it = packets.begin();
133          it != packets.end(); ++it) {
134         sp<ABuffer> nal = *it;
135         memcpy(accessUnit->data() + offset, nal->data(), nal->size());
136         offset += nal->size();
137     }
138 
139     CopyTimes(accessUnit, *packets.begin());
140 
141     return accessUnit;
142 }
143 
144 }  // namespace android
145