xref: /aosp_15_r20/frameworks/av/media/libstagefright/rtsp/AH263Assembler.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 //#define LOG_NDEBUG 0
17 #define LOG_TAG "AH263Assembler"
18 #include <utils/Log.h>
19 
20 #include <media/stagefright/rtsp/AH263Assembler.h>
21 
22 #include <media/stagefright/rtsp/ARTPSource.h>
23 
24 #include <media/stagefright/foundation/ABuffer.h>
25 #include <media/stagefright/foundation/ADebug.h>
26 #include <media/stagefright/foundation/AMessage.h>
27 #include <media/stagefright/foundation/hexdump.h>
28 #include <media/stagefright/foundation/ByteUtils.h>
29 
30 namespace android {
31 
AH263Assembler(const sp<AMessage> & notify)32 AH263Assembler::AH263Assembler(const sp<AMessage> &notify)
33     : mNotifyMsg(notify),
34       mAccessUnitRTPTime(0),
35       mNextExpectedSeqNoValid(false),
36       mNextExpectedSeqNo(0),
37       mAccessUnitDamaged(false) {
38 }
39 
~AH263Assembler()40 AH263Assembler::~AH263Assembler() {
41 }
42 
assembleMore(const sp<ARTPSource> & source)43 ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
44         const sp<ARTPSource> &source) {
45     AssemblyStatus status = addPacket(source);
46     if (status == MALFORMED_PACKET) {
47         mAccessUnitDamaged = true;
48     }
49     return status;
50 }
51 
addPacket(const sp<ARTPSource> & source)52 ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
53         const sp<ARTPSource> &source) {
54     List<sp<ABuffer> > *queue = source->queue();
55 
56     if (queue->empty()) {
57         return NOT_ENOUGH_DATA;
58     }
59 
60     if (mNextExpectedSeqNoValid) {
61         List<sp<ABuffer> >::iterator it = queue->begin();
62         while (it != queue->end()) {
63             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
64                 break;
65             }
66 
67             it = queue->erase(it);
68         }
69 
70         if (queue->empty()) {
71             return NOT_ENOUGH_DATA;
72         }
73     }
74 
75     sp<ABuffer> buffer = *queue->begin();
76 
77     if (!mNextExpectedSeqNoValid) {
78         mNextExpectedSeqNoValid = true;
79         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
80     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
81 #if VERBOSE
82         LOG(VERBOSE) << "Not the sequence number I expected";
83 #endif
84 
85         return WRONG_SEQUENCE_NUMBER;
86     }
87 
88     uint32_t rtpTime;
89     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
90 
91     if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
92         submitAccessUnit();
93     }
94     mAccessUnitRTPTime = rtpTime;
95 
96     // hexdump(buffer->data(), buffer->size());
97 
98     if (buffer->size() < 2) {
99         queue->erase(queue->begin());
100         ++mNextExpectedSeqNo;
101 
102         return MALFORMED_PACKET;
103     }
104 
105     unsigned payloadHeader = U16_AT(buffer->data());
106     unsigned P = (payloadHeader >> 10) & 1;
107     unsigned V = (payloadHeader >> 9) & 1;
108     unsigned PLEN = (payloadHeader >> 3) & 0x3f;
109     unsigned PEBIT = payloadHeader & 7;
110 
111     // V=0
112     if (V != 0u) {
113         queue->erase(queue->begin());
114         ++mNextExpectedSeqNo;
115         ALOGW("Packet discarded due to VRC (V != 0)");
116         return MALFORMED_PACKET;
117     }
118 
119     // PLEN=0
120     if (PLEN != 0u) {
121         queue->erase(queue->begin());
122         ++mNextExpectedSeqNo;
123         ALOGW("Packet discarded (PLEN != 0)");
124         return MALFORMED_PACKET;
125     }
126 
127     // PEBIT=0
128     if (PEBIT != 0u) {
129         queue->erase(queue->begin());
130         ++mNextExpectedSeqNo;
131         ALOGW("Packet discarded (PEBIT != 0)");
132         return MALFORMED_PACKET;
133     }
134 
135     size_t skip = V + PLEN + (P ? 0 : 2);
136 
137     buffer->setRange(buffer->offset() + skip, buffer->size() - skip);
138 
139     if (P) {
140         buffer->data()[0] = 0x00;
141         buffer->data()[1] = 0x00;
142     }
143 
144     mPackets.push_back(buffer);
145 
146     queue->erase(queue->begin());
147     ++mNextExpectedSeqNo;
148 
149     return OK;
150 }
151 
submitAccessUnit()152 void AH263Assembler::submitAccessUnit() {
153     CHECK(!mPackets.empty());
154 
155 #if VERBOSE
156     LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
157 #endif
158 
159     size_t totalSize = 0;
160     List<sp<ABuffer> >::iterator it = mPackets.begin();
161     while (it != mPackets.end()) {
162         const sp<ABuffer> &unit = *it;
163 
164         totalSize += unit->size();
165         ++it;
166     }
167 
168     sp<ABuffer> accessUnit = new ABuffer(totalSize);
169     size_t offset = 0;
170     it = mPackets.begin();
171     while (it != mPackets.end()) {
172         const sp<ABuffer> &unit = *it;
173 
174         memcpy((uint8_t *)accessUnit->data() + offset,
175                unit->data(), unit->size());
176 
177         offset += unit->size();
178 
179         ++it;
180     }
181 
182     CopyTimes(accessUnit, *mPackets.begin());
183 
184 #if 0
185     printf(mAccessUnitDamaged ? "X" : ".");
186     fflush(stdout);
187 #endif
188 
189     if (mAccessUnitDamaged) {
190         accessUnit->meta()->setInt32("damaged", true);
191     }
192 
193     mPackets.clear();
194     mAccessUnitDamaged = false;
195 
196     sp<AMessage> msg = mNotifyMsg->dup();
197     msg->setBuffer("access-unit", accessUnit);
198     msg->post();
199 }
200 
packetLost()201 void AH263Assembler::packetLost() {
202     CHECK(mNextExpectedSeqNoValid);
203     ++mNextExpectedSeqNo;
204 
205     mAccessUnitDamaged = true;
206 }
207 
onByeReceived()208 void AH263Assembler::onByeReceived() {
209     sp<AMessage> msg = mNotifyMsg->dup();
210     msg->setInt32("eos", true);
211     msg->post();
212 }
213 
214 }  // namespace android
215 
216