AH263Assembler.cpp revision a6238a1e5b603ca2ccf3b2297c9bc8a141cf8559
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
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 {
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
124void AH263Assembler::submitAccessUnit() {
125    CHECK(!mPackets.empty());
126
127#if VERBOSE
128    LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
129#endif
130
131    uint64_t ntpTime;
132    CHECK((*mPackets.begin())->meta()->findInt64(
133                "ntp-time", (int64_t *)&ntpTime));
134
135    size_t totalSize = 0;
136    List<sp<ABuffer> >::iterator it = mPackets.begin();
137    while (it != mPackets.end()) {
138        const sp<ABuffer> &unit = *it;
139
140        totalSize += unit->size();
141        ++it;
142    }
143
144    sp<ABuffer> accessUnit = new ABuffer(totalSize);
145    size_t offset = 0;
146    it = mPackets.begin();
147    while (it != mPackets.end()) {
148        const sp<ABuffer> &unit = *it;
149
150        memcpy((uint8_t *)accessUnit->data() + offset,
151               unit->data(), unit->size());
152
153        offset += unit->size();
154
155        ++it;
156    }
157
158    accessUnit->meta()->setInt64("ntp-time", ntpTime);
159
160#if 0
161    printf(mAccessUnitDamaged ? "X" : ".");
162    fflush(stdout);
163#endif
164
165    if (mAccessUnitDamaged) {
166        accessUnit->meta()->setInt32("damaged", true);
167    }
168
169    mPackets.clear();
170    mAccessUnitDamaged = false;
171
172    sp<AMessage> msg = mNotifyMsg->dup();
173    msg->setObject("access-unit", accessUnit);
174    msg->post();
175}
176
177void AH263Assembler::packetLost() {
178    CHECK(mNextExpectedSeqNoValid);
179    ++mNextExpectedSeqNo;
180
181    mAccessUnitDamaged = true;
182}
183
184void AH263Assembler::onByeReceived() {
185    sp<AMessage> msg = mNotifyMsg->dup();
186    msg->setInt32("eos", true);
187    msg->post();
188}
189
190}  // namespace android
191
192