1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/*
2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License.
6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at
7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and
14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License.
15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */
16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "AAVCAssembler"
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h>
206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "AAVCAssembler.h"
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPSource.h"
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/hexdump.h>
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <stdint.h>
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAAVCAssembler::AAVCAssembler(const sp<AMessage> &notify)
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    : mNotifyMsg(notify),
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mAccessUnitRTPTime(0),
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mNextExpectedSeqNoValid(false),
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mNextExpectedSeqNo(0),
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mAccessUnitDamaged(false) {
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberAAVCAssembler::~AAVCAssembler() {
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ARTPSource> &source) {
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    List<sp<ABuffer> > *queue = source->queue();
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (queue->empty()) {
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return NOT_ENOUGH_DATA;
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mNextExpectedSeqNoValid) {
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        List<sp<ABuffer> >::iterator it = queue->begin();
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        while (it != queue->end()) {
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            it = queue->erase(it);
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (queue->empty()) {
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return NOT_ENOUGH_DATA;
66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> buffer = *queue->begin();
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mNextExpectedSeqNoValid) {
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mNextExpectedSeqNoValid = true;
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Not the sequence number I expected");
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return WRONG_SEQUENCE_NUMBER;
78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = buffer->data();
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t size = buffer->size();
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size < 1 || (data[0] & 0x80)) {
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Corrupt.
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Ignoring corrupt buffer.");
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        queue->erase(queue->begin());
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++mNextExpectedSeqNo;
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return MALFORMED_PACKET;
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned nalType = data[0] & 0x1f;
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (nalType >= 1 && nalType <= 23) {
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        addSingleNALUnit(buffer);
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        queue->erase(queue->begin());
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++mNextExpectedSeqNo;
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return OK;
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if (nalType == 28) {
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // FU-A
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return addFragmentedNALUnit(queue);
102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if (nalType == 24) {
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // STAP-A
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        bool success = addSingleTimeAggregationPacket(buffer);
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        queue->erase(queue->begin());
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++mNextExpectedSeqNo;
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return success ? OK : MALFORMED_PACKET;
109a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik    } else if (nalType == 0) {
110a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik        ALOGV("Ignoring undefined nal type.");
111a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik
112a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik        queue->erase(queue->begin());
113a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik        ++mNextExpectedSeqNo;
114a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik
115a355bb4f5ce39a77d05f62263d4be888e903c4cdPatrik        return OK;
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
1173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        queue->erase(queue->begin());
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++mNextExpectedSeqNo;
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return MALFORMED_PACKET;
123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
127b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    ALOGV("addSingleNALUnit of size %zu", buffer->size());
1286e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#if !LOG_NDEBUG
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    hexdump(buffer->data(), buffer->size());
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t rtpTime;
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) {
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        submitAccessUnit();
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mAccessUnitRTPTime = rtpTime;
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mNALUnits.push_back(buffer);
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) {
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = buffer->data();
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t size = buffer->size();
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size < 3) {
1483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Discarding too small STAP-A packet.");
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    ++data;
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    --size;
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (size >= 2) {
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t nalSize = (data[0] << 8) | data[1];
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (size < nalSize + 2) {
1583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Discarding malformed STAP-A packet.");
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return false;
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> unit = new ABuffer(nalSize);
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(unit->data(), &data[2], nalSize);
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
1658d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber        CopyTimes(unit, buffer);
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        addSingleNALUnit(unit);
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        data += 2 + nalSize;
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size -= 2 + nalSize;
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size != 0) {
1743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Unexpected padding at end of STAP-A packet.");
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        List<sp<ABuffer> > *queue) {
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(!queue->empty());
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> buffer = *queue->begin();
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = buffer->data();
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t size = buffer->size();
187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(size > 0);
189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned indicator = data[0];
190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK((indicator & 0x1f) == 28);
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size < 2) {
194b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        ALOGV("Ignoring malformed FU buffer (size = %zu)", size);
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        queue->erase(queue->begin());
197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++mNextExpectedSeqNo;
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return MALFORMED_PACKET;
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!(data[1] & 0x80)) {
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Start bit not set on the first buffer.
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Start bit not set on first buffer");
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        queue->erase(queue->begin());
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++mNextExpectedSeqNo;
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return MALFORMED_PACKET;
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t nalType = data[1] & 0x1f;
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t nri = (data[0] >> 5) & 3;
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1;
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalSize = size - 2;
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalCount = 1;
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    bool complete = false;
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (data[1] & 0x40) {
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Huh? End bit also set on the first buffer.
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Grrr. This isn't fragmented at all.");
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        complete = true;
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        List<sp<ABuffer> >::iterator it = ++queue->begin();
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        while (it != queue->end()) {
228b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("sequence length %zu", totalCount);
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            const sp<ABuffer> &buffer = *it;
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            const uint8_t *data = buffer->data();
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            size_t size = buffer->size();
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
2363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("sequence not complete, expected seqNo %d, got %d",
2376e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber                     expectedSeqNo, (uint32_t)buffer->int32Data());
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                return WRONG_SEQUENCE_NUMBER;
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (size < 2
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    || data[0] != indicator
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    || (data[1] & 0x1f) != nalType
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    || (data[1] & 0x80)) {
2463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("Ignoring malformed FU buffer.");
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                // Delete the whole start of the FU.
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                it = queue->begin();
251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                for (size_t i = 0; i <= totalCount; ++i) {
252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    it = queue->erase(it);
253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
255cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                mNextExpectedSeqNo = expectedSeqNo + 1;
256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                return MALFORMED_PACKET;
258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            totalSize += size - 2;
261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++totalCount;
262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            expectedSeqNo = expectedSeqNo + 1;
264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (data[1] & 0x40) {
266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                // This is the last fragment.
267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                complete = true;
268cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++it;
272cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
273cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
274cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
275cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!complete) {
276cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return NOT_ENOUGH_DATA;
277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
278cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
279cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mNextExpectedSeqNo = expectedSeqNo;
280cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // We found all the fragments that make up the complete NAL unit.
282cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
283cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // Leave room for the header. So far totalSize did not include the
284cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // header byte.
285cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    ++totalSize;
286cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
287cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> unit = new ABuffer(totalSize);
2888d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CopyTimes(unit, *queue->begin());
289cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
290cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unit->data()[0] = (nri << 5) | nalType;
291cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
292cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t offset = 1;
293cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    List<sp<ABuffer> >::iterator it = queue->begin();
294cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (size_t i = 0; i < totalCount; ++i) {
295cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ABuffer> &buffer = *it;
296cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
297b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        ALOGV("piece #%zu/%zu", i + 1, totalCount);
2986e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#if !LOG_NDEBUG
299cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        hexdump(buffer->data(), buffer->size());
300cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif
301cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
302cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2);
303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        offset += buffer->size() - 2;
304cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
305cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        it = queue->erase(it);
306cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
307cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
308cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unit->setRange(0, totalSize);
309cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
310cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    addSingleNALUnit(unit);
311cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
3123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("successfully assembled a NAL unit from fragments.");
313cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
314cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
315cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
316cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
317cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid AAVCAssembler::submitAccessUnit() {
318cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(!mNALUnits.empty());
319cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
320b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    ALOGV("Access unit complete (%zu nal units)", mNALUnits.size());
321cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
322cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t totalSize = 0;
323cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
324cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber         it != mNALUnits.end(); ++it) {
325cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        totalSize += 4 + (*it)->size();
326cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
327cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
328cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(totalSize);
329cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t offset = 0;
330cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
331cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber         it != mNALUnits.end(); ++it) {
332cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
333cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        offset += 4;
334cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
335cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<ABuffer> nal = *it;
336cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memcpy(accessUnit->data() + offset, nal->data(), nal->size());
337cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        offset += nal->size();
338cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
339cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
3408d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CopyTimes(accessUnit, *mNALUnits.begin());
341cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
342cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if 0
343cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    printf(mAccessUnitDamaged ? "X" : ".");
344cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    fflush(stdout);
345cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif
346cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
347cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mAccessUnitDamaged) {
348cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        accessUnit->meta()->setInt32("damaged", true);
349cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
350cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
351cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mNALUnits.clear();
352cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mAccessUnitDamaged = false;
353cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
354cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<AMessage> msg = mNotifyMsg->dup();
3552d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    msg->setBuffer("access-unit", accessUnit);
356cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->post();
357cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
358cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
359cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
360cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ARTPSource> &source) {
361cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AssemblyStatus status = addNALUnit(source);
362cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (status == MALFORMED_PACKET) {
363cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mAccessUnitDamaged = true;
364cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
365cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return status;
366cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
367cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
368cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid AAVCAssembler::packetLost() {
369cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(mNextExpectedSeqNoValid);
3703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("packetLost (expected %d)", mNextExpectedSeqNo);
37139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
372cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    ++mNextExpectedSeqNo;
373cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
374cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mAccessUnitDamaged = true;
375cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
37739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid AAVCAssembler::onByeReceived() {
37839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<AMessage> msg = mNotifyMsg->dup();
37939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->setInt32("eos", true);
38039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->post();
38139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
38239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
383cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
384