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