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