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