blob: 498295c46e1b16912ade2085d4f59e9dbb692ef1 [file] [log] [blame]
Andreas Huber57648e42010-08-04 10:14:30 -07001/*
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 "AH263Assembler.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#include <media/stagefright/Utils.h>
26
27namespace android {
28
29AH263Assembler::AH263Assembler(const sp<AMessage> &notify)
30 : mNotifyMsg(notify),
31 mAccessUnitRTPTime(0),
32 mNextExpectedSeqNoValid(false),
33 mNextExpectedSeqNo(0),
34 mAccessUnitDamaged(false) {
35}
36
37AH263Assembler::~AH263Assembler() {
38}
39
40ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
41 const sp<ARTPSource> &source) {
42 AssemblyStatus status = addPacket(source);
43 if (status == MALFORMED_PACKET) {
44 mAccessUnitDamaged = true;
45 }
46 return status;
47}
48
49ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
50 const sp<ARTPSource> &source) {
51 List<sp<ABuffer> > *queue = source->queue();
52
53 if (queue->empty()) {
54 return NOT_ENOUGH_DATA;
55 }
56
57 if (mNextExpectedSeqNoValid) {
58 List<sp<ABuffer> >::iterator it = queue->begin();
59 while (it != queue->end()) {
60 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
61 break;
62 }
63
64 it = queue->erase(it);
65 }
66
67 if (queue->empty()) {
68 return NOT_ENOUGH_DATA;
69 }
70 }
71
72 sp<ABuffer> buffer = *queue->begin();
73
74 if (!mNextExpectedSeqNoValid) {
75 mNextExpectedSeqNoValid = true;
76 mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
77 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
78#if VERBOSE
79 LOG(VERBOSE) << "Not the sequence number I expected";
80#endif
81
82 return WRONG_SEQUENCE_NUMBER;
83 }
84
85 uint32_t rtpTime;
86 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
87
88 if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
89 submitAccessUnit();
90 }
91 mAccessUnitRTPTime = rtpTime;
92
93 // hexdump(buffer->data(), buffer->size());
94
95 if (buffer->size() < 2) {
96 queue->erase(queue->begin());
97 ++mNextExpectedSeqNo;
98
99 return MALFORMED_PACKET;
100 }
101
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
108
109 if (P) {
110 buffer->data()[0] = 0x00;
111 buffer->data()[1] = 0x00;
112 } else {
Andreas Huber00237b72010-08-12 10:58:24 -0700113 buffer->setRange(buffer->offset() + 2, buffer->size() - 2);
Andreas Huber57648e42010-08-04 10:14:30 -0700114 }
115
116 mPackets.push_back(buffer);
117
118 queue->erase(queue->begin());
119 ++mNextExpectedSeqNo;
120
121 return OK;
122}
123
124void AH263Assembler::submitAccessUnit() {
125 CHECK(!mPackets.empty());
126
127#if VERBOSE
128 LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
129#endif
130
Andreas Huber57648e42010-08-04 10:14:30 -0700131 size_t totalSize = 0;
132 List<sp<ABuffer> >::iterator it = mPackets.begin();
133 while (it != mPackets.end()) {
134 const sp<ABuffer> &unit = *it;
135
136 totalSize += unit->size();
137 ++it;
138 }
139
140 sp<ABuffer> accessUnit = new ABuffer(totalSize);
141 size_t offset = 0;
142 it = mPackets.begin();
143 while (it != mPackets.end()) {
144 const sp<ABuffer> &unit = *it;
145
146 memcpy((uint8_t *)accessUnit->data() + offset,
147 unit->data(), unit->size());
148
149 offset += unit->size();
150
151 ++it;
152 }
153
Andreas Hubereeb97d92010-08-27 13:29:08 -0700154 CopyTimes(accessUnit, *mPackets.begin());
Andreas Huber57648e42010-08-04 10:14:30 -0700155
156#if 0
157 printf(mAccessUnitDamaged ? "X" : ".");
158 fflush(stdout);
159#endif
160
161 if (mAccessUnitDamaged) {
162 accessUnit->meta()->setInt32("damaged", true);
163 }
164
165 mPackets.clear();
166 mAccessUnitDamaged = false;
167
168 sp<AMessage> msg = mNotifyMsg->dup();
169 msg->setObject("access-unit", accessUnit);
170 msg->post();
171}
172
173void AH263Assembler::packetLost() {
174 CHECK(mNextExpectedSeqNoValid);
175 ++mNextExpectedSeqNo;
176
177 mAccessUnitDamaged = true;
178}
179
180void AH263Assembler::onByeReceived() {
181 sp<AMessage> msg = mNotifyMsg->dup();
182 msg->setInt32("eos", true);
183 msg->post();
184}
185
186} // namespace android
187