2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "AH263Assembler.h"
19 #include "ARTPSource.h"
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 #include <media/stagefright/Utils.h>
29 AH263Assembler::AH263Assembler(const sp<AMessage> ¬ify)
31 mAccessUnitRTPTime(0),
32 mNextExpectedSeqNoValid(false),
33 mNextExpectedSeqNo(0),
34 mAccessUnitDamaged(false) {
37 AH263Assembler::~AH263Assembler() {
40 ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
41 const sp<ARTPSource> &source) {
42 AssemblyStatus status = addPacket(source);
43 if (status == MALFORMED_PACKET) {
44 mAccessUnitDamaged = true;
49 ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
50 const sp<ARTPSource> &source) {
51 List<sp<ABuffer> > *queue = source->queue();
54 return NOT_ENOUGH_DATA;
57 if (mNextExpectedSeqNoValid) {
58 List<sp<ABuffer> >::iterator it = queue->begin();
59 while (it != queue->end()) {
60 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
64 it = queue->erase(it);
68 return NOT_ENOUGH_DATA;
72 sp<ABuffer> buffer = *queue->begin();
74 if (!mNextExpectedSeqNoValid) {
75 mNextExpectedSeqNoValid = true;
76 mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
77 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
79 LOG(VERBOSE) << "Not the sequence number I expected";
82 return WRONG_SEQUENCE_NUMBER;
86 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
88 if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
91 mAccessUnitRTPTime = rtpTime;
93 // hexdump(buffer->data(), buffer->size());
95 if (buffer->size() < 2) {
96 queue->erase(queue->begin());
99 return MALFORMED_PACKET;
102 unsigned payloadHeader = U16_AT(buffer->data());
103 CHECK_EQ(payloadHeader >> 11, 0u); // RR=0
104 unsigned P = (payloadHeader >> 10) & 1;
105 CHECK_EQ((payloadHeader >> 9) & 1, 0u); // V=0
106 CHECK_EQ((payloadHeader >> 3) & 0x3f, 0u); // PLEN=0
107 CHECK_EQ(payloadHeader & 7, 0u); // PEBIT=0
110 buffer->data()[0] = 0x00;
111 buffer->data()[1] = 0x00;
113 buffer->setRange(buffer->offset() + 2, buffer->size() - 2);
116 mPackets.push_back(buffer);
118 queue->erase(queue->begin());
119 ++mNextExpectedSeqNo;
124 void AH263Assembler::submitAccessUnit() {
125 CHECK(!mPackets.empty());
128 LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
131 size_t totalSize = 0;
132 List<sp<ABuffer> >::iterator it = mPackets.begin();
133 while (it != mPackets.end()) {
134 const sp<ABuffer> &unit = *it;
136 totalSize += unit->size();
140 sp<ABuffer> accessUnit = new ABuffer(totalSize);
142 it = mPackets.begin();
143 while (it != mPackets.end()) {
144 const sp<ABuffer> &unit = *it;
146 memcpy((uint8_t *)accessUnit->data() + offset,
147 unit->data(), unit->size());
149 offset += unit->size();
154 CopyTimes(accessUnit, *mPackets.begin());
157 printf(mAccessUnitDamaged ? "X" : ".");
161 if (mAccessUnitDamaged) {
162 accessUnit->meta()->setInt32("damaged", true);
166 mAccessUnitDamaged = false;
168 sp<AMessage> msg = mNotifyMsg->dup();
169 msg->setObject("access-unit", accessUnit);
173 void AH263Assembler::packetLost() {
174 CHECK(mNextExpectedSeqNoValid);
175 ++mNextExpectedSeqNo;
177 mAccessUnitDamaged = true;
180 void AH263Assembler::onByeReceived() {
181 sp<AMessage> msg = mNotifyMsg->dup();
182 msg->setInt32("eos", true);
186 } // namespace android