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_NDEBUG 0
18 #define LOG_TAG "AAVCAssembler"
19 #include <utils/Log.h>
20 
21 #include "AAVCAssembler.h"
22 
23 #include "ARTPSource.h"
24 
25 #include <media/stagefright/foundation/ABuffer.h>
26 #include <media/stagefright/foundation/ADebug.h>
27 #include <media/stagefright/foundation/AMessage.h>
28 #include <media/stagefright/foundation/hexdump.h>
29 
30 #include <stdint.h>
31 
32 namespace android {
33 
34 // static
AAVCAssembler(const sp<AMessage> & notify)35 AAVCAssembler::AAVCAssembler(const sp<AMessage> &notify)
36     : mNotifyMsg(notify),
37       mAccessUnitRTPTime(0),
38       mNextExpectedSeqNoValid(false),
39       mNextExpectedSeqNo(0),
40       mAccessUnitDamaged(false) {
41 }
42 
~AAVCAssembler()43 AAVCAssembler::~AAVCAssembler() {
44 }
45 
addNALUnit(const sp<ARTPSource> & source)46 ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
47         const sp<ARTPSource> &source) {
48     List<sp<ABuffer> > *queue = source->queue();
49 
50     if (queue->empty()) {
51         return NOT_ENOUGH_DATA;
52     }
53 
54     if (mNextExpectedSeqNoValid) {
55         List<sp<ABuffer> >::iterator it = queue->begin();
56         while (it != queue->end()) {
57             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
58                 break;
59             }
60 
61             it = queue->erase(it);
62         }
63 
64         if (queue->empty()) {
65             return NOT_ENOUGH_DATA;
66         }
67     }
68 
69     sp<ABuffer> buffer = *queue->begin();
70 
71     if (!mNextExpectedSeqNoValid) {
72         mNextExpectedSeqNoValid = true;
73         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
74     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
75         ALOGV("Not the sequence number I expected");
76 
77         return WRONG_SEQUENCE_NUMBER;
78     }
79 
80     const uint8_t *data = buffer->data();
81     size_t size = buffer->size();
82 
83     if (size < 1 || (data[0] & 0x80)) {
84         // Corrupt.
85 
86         ALOGV("Ignoring corrupt buffer.");
87         queue->erase(queue->begin());
88 
89         ++mNextExpectedSeqNo;
90         return MALFORMED_PACKET;
91     }
92 
93     unsigned nalType = data[0] & 0x1f;
94     if (nalType >= 1 && nalType <= 23) {
95         addSingleNALUnit(buffer);
96         queue->erase(queue->begin());
97         ++mNextExpectedSeqNo;
98         return OK;
99     } else if (nalType == 28) {
100         // FU-A
101         return addFragmentedNALUnit(queue);
102     } else if (nalType == 24) {
103         // STAP-A
104         bool success = addSingleTimeAggregationPacket(buffer);
105         queue->erase(queue->begin());
106         ++mNextExpectedSeqNo;
107 
108         return success ? OK : MALFORMED_PACKET;
109     } else if (nalType == 0) {
110         ALOGV("Ignoring undefined nal type.");
111 
112         queue->erase(queue->begin());
113         ++mNextExpectedSeqNo;
114 
115         return OK;
116     } else {
117         ALOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
118 
119         queue->erase(queue->begin());
120         ++mNextExpectedSeqNo;
121 
122         return MALFORMED_PACKET;
123     }
124 }
125 
addSingleNALUnit(const sp<ABuffer> & buffer)126 void AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
127     ALOGV("addSingleNALUnit of size %zu", buffer->size());
128 #if !LOG_NDEBUG
129     hexdump(buffer->data(), buffer->size());
130 #endif
131 
132     uint32_t rtpTime;
133     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
134 
135     if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) {
136         submitAccessUnit();
137     }
138     mAccessUnitRTPTime = rtpTime;
139 
140     mNALUnits.push_back(buffer);
141 }
142 
addSingleTimeAggregationPacket(const sp<ABuffer> & buffer)143 bool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) {
144     const uint8_t *data = buffer->data();
145     size_t size = buffer->size();
146 
147     if (size < 3) {
148         ALOGV("Discarding too small STAP-A packet.");
149         return false;
150     }
151 
152     ++data;
153     --size;
154     while (size >= 2) {
155         size_t nalSize = (data[0] << 8) | data[1];
156 
157         if (size < nalSize + 2) {
158             ALOGV("Discarding malformed STAP-A packet.");
159             return false;
160         }
161 
162         sp<ABuffer> unit = new ABuffer(nalSize);
163         memcpy(unit->data(), &data[2], nalSize);
164 
165         CopyTimes(unit, buffer);
166 
167         addSingleNALUnit(unit);
168 
169         data += 2 + nalSize;
170         size -= 2 + nalSize;
171     }
172 
173     if (size != 0) {
174         ALOGV("Unexpected padding at end of STAP-A packet.");
175     }
176 
177     return true;
178 }
179 
addFragmentedNALUnit(List<sp<ABuffer>> * queue)180 ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
181         List<sp<ABuffer> > *queue) {
182     CHECK(!queue->empty());
183 
184     sp<ABuffer> buffer = *queue->begin();
185     const uint8_t *data = buffer->data();
186     size_t size = buffer->size();
187 
188     CHECK(size > 0);
189     unsigned indicator = data[0];
190 
191     CHECK((indicator & 0x1f) == 28);
192 
193     if (size < 2) {
194         ALOGV("Ignoring malformed FU buffer (size = %zu)", size);
195 
196         queue->erase(queue->begin());
197         ++mNextExpectedSeqNo;
198         return MALFORMED_PACKET;
199     }
200 
201     if (!(data[1] & 0x80)) {
202         // Start bit not set on the first buffer.
203 
204         ALOGV("Start bit not set on first buffer");
205 
206         queue->erase(queue->begin());
207         ++mNextExpectedSeqNo;
208         return MALFORMED_PACKET;
209     }
210 
211     uint32_t nalType = data[1] & 0x1f;
212     uint32_t nri = (data[0] >> 5) & 3;
213 
214     uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1;
215     size_t totalSize = size - 2;
216     size_t totalCount = 1;
217     bool complete = false;
218 
219     if (data[1] & 0x40) {
220         // Huh? End bit also set on the first buffer.
221 
222         ALOGV("Grrr. This isn't fragmented at all.");
223 
224         complete = true;
225     } else {
226         List<sp<ABuffer> >::iterator it = ++queue->begin();
227         while (it != queue->end()) {
228             ALOGV("sequence length %zu", totalCount);
229 
230             const sp<ABuffer> &buffer = *it;
231 
232             const uint8_t *data = buffer->data();
233             size_t size = buffer->size();
234 
235             if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
236                 ALOGV("sequence not complete, expected seqNo %d, got %d",
237                      expectedSeqNo, (uint32_t)buffer->int32Data());
238 
239                 return WRONG_SEQUENCE_NUMBER;
240             }
241 
242             if (size < 2
243                     || data[0] != indicator
244                     || (data[1] & 0x1f) != nalType
245                     || (data[1] & 0x80)) {
246                 ALOGV("Ignoring malformed FU buffer.");
247 
248                 // Delete the whole start of the FU.
249 
250                 it = queue->begin();
251                 for (size_t i = 0; i <= totalCount; ++i) {
252                     it = queue->erase(it);
253                 }
254 
255                 mNextExpectedSeqNo = expectedSeqNo + 1;
256 
257                 return MALFORMED_PACKET;
258             }
259 
260             totalSize += size - 2;
261             ++totalCount;
262 
263             expectedSeqNo = expectedSeqNo + 1;
264 
265             if (data[1] & 0x40) {
266                 // This is the last fragment.
267                 complete = true;
268                 break;
269             }
270 
271             ++it;
272         }
273     }
274 
275     if (!complete) {
276         return NOT_ENOUGH_DATA;
277     }
278 
279     mNextExpectedSeqNo = expectedSeqNo;
280 
281     // We found all the fragments that make up the complete NAL unit.
282 
283     // Leave room for the header. So far totalSize did not include the
284     // header byte.
285     ++totalSize;
286 
287     sp<ABuffer> unit = new ABuffer(totalSize);
288     CopyTimes(unit, *queue->begin());
289 
290     unit->data()[0] = (nri << 5) | nalType;
291 
292     size_t offset = 1;
293     List<sp<ABuffer> >::iterator it = queue->begin();
294     for (size_t i = 0; i < totalCount; ++i) {
295         const sp<ABuffer> &buffer = *it;
296 
297         ALOGV("piece #%zu/%zu", i + 1, totalCount);
298 #if !LOG_NDEBUG
299         hexdump(buffer->data(), buffer->size());
300 #endif
301 
302         memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2);
303         offset += buffer->size() - 2;
304 
305         it = queue->erase(it);
306     }
307 
308     unit->setRange(0, totalSize);
309 
310     addSingleNALUnit(unit);
311 
312     ALOGV("successfully assembled a NAL unit from fragments.");
313 
314     return OK;
315 }
316 
submitAccessUnit()317 void AAVCAssembler::submitAccessUnit() {
318     CHECK(!mNALUnits.empty());
319 
320     ALOGV("Access unit complete (%zu nal units)", mNALUnits.size());
321 
322     size_t totalSize = 0;
323     for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
324          it != mNALUnits.end(); ++it) {
325         totalSize += 4 + (*it)->size();
326     }
327 
328     sp<ABuffer> accessUnit = new ABuffer(totalSize);
329     size_t offset = 0;
330     for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
331          it != mNALUnits.end(); ++it) {
332         memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
333         offset += 4;
334 
335         sp<ABuffer> nal = *it;
336         memcpy(accessUnit->data() + offset, nal->data(), nal->size());
337         offset += nal->size();
338     }
339 
340     CopyTimes(accessUnit, *mNALUnits.begin());
341 
342 #if 0
343     printf(mAccessUnitDamaged ? "X" : ".");
344     fflush(stdout);
345 #endif
346 
347     if (mAccessUnitDamaged) {
348         accessUnit->meta()->setInt32("damaged", true);
349     }
350 
351     mNALUnits.clear();
352     mAccessUnitDamaged = false;
353 
354     sp<AMessage> msg = mNotifyMsg->dup();
355     msg->setBuffer("access-unit", accessUnit);
356     msg->post();
357 }
358 
assembleMore(const sp<ARTPSource> & source)359 ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
360         const sp<ARTPSource> &source) {
361     AssemblyStatus status = addNALUnit(source);
362     if (status == MALFORMED_PACKET) {
363         mAccessUnitDamaged = true;
364     }
365     return status;
366 }
367 
packetLost()368 void AAVCAssembler::packetLost() {
369     CHECK(mNextExpectedSeqNoValid);
370     ALOGV("packetLost (expected %d)", mNextExpectedSeqNo);
371 
372     ++mNextExpectedSeqNo;
373 
374     mAccessUnitDamaged = true;
375 }
376 
onByeReceived()377 void AAVCAssembler::onByeReceived() {
378     sp<AMessage> msg = mNotifyMsg->dup();
379     msg->setInt32("eos", true);
380     msg->post();
381 }
382 
383 }  // namespace android
384