OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libstagefright / rtsp / AH263Assembler.cpp
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 "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
27 namespace android {
28
29 AH263Assembler::AH263Assembler(const sp<AMessage> &notify)
30     : mNotifyMsg(notify),
31       mAccessUnitRTPTime(0),
32       mNextExpectedSeqNoValid(false),
33       mNextExpectedSeqNo(0),
34       mAccessUnitDamaged(false) {
35 }
36
37 AH263Assembler::~AH263Assembler() {
38 }
39
40 ARTPAssembler::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
49 ARTPAssembler::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 {
113         buffer->setRange(buffer->offset() + 2, buffer->size() - 2);
114     }
115
116     mPackets.push_back(buffer);
117
118     queue->erase(queue->begin());
119     ++mNextExpectedSeqNo;
120
121     return OK;
122 }
123
124 void AH263Assembler::submitAccessUnit() {
125     CHECK(!mPackets.empty());
126
127 #if VERBOSE
128     LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
129 #endif
130
131     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
154     CopyTimes(accessUnit, *mPackets.begin());
155
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
173 void AH263Assembler::packetLost() {
174     CHECK(mNextExpectedSeqNoValid);
175     ++mNextExpectedSeqNo;
176
177     mAccessUnitDamaged = true;
178 }
179
180 void AH263Assembler::onByeReceived() {
181     sp<AMessage> msg = mNotifyMsg->dup();
182     msg->setInt32("eos", true);
183     msg->post();
184 }
185
186 }  // namespace android
187