1/*
2 * Copyright (C) 2012 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//#define LOG_NDEBUG 0
18#define LOG_TAG "AMPEG2TSAssembler"
19#include <utils/Log.h>
20
21#include "AMPEG2TSAssembler.h"
22
23#include "ARTPSource.h"
24#include "ASessionDescription.h"
25
26#include <media/stagefright/foundation/ABuffer.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
29#include <media/stagefright/foundation/hexdump.h>
30#include <media/stagefright/MediaDefs.h>
31#include <media/stagefright/MetaData.h>
32#include <media/stagefright/Utils.h>
33
34namespace android {
35
36AMPEG2TSAssembler::AMPEG2TSAssembler(
37        const sp<AMessage> &notify,
38        const char * /* desc */,
39        const AString & /* params */)
40    : mNotifyMsg(notify),
41      mNextExpectedSeqNoValid(false),
42      mNextExpectedSeqNo(0) {
43}
44
45AMPEG2TSAssembler::~AMPEG2TSAssembler() {
46}
47
48ARTPAssembler::AssemblyStatus AMPEG2TSAssembler::assembleMore(
49        const sp<ARTPSource> &source) {
50    return addPacket(source);
51}
52
53ARTPAssembler::AssemblyStatus AMPEG2TSAssembler::addPacket(
54        const sp<ARTPSource> &source) {
55    List<sp<ABuffer> > *queue = source->queue();
56
57    if (queue->empty()) {
58        return NOT_ENOUGH_DATA;
59    }
60
61    if (mNextExpectedSeqNoValid) {
62        List<sp<ABuffer> >::iterator it = queue->begin();
63        while (it != queue->end()) {
64            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
65                break;
66            }
67
68            it = queue->erase(it);
69        }
70
71        if (queue->empty()) {
72            return NOT_ENOUGH_DATA;
73        }
74    }
75
76    sp<ABuffer> buffer = *queue->begin();
77
78    if (!mNextExpectedSeqNoValid) {
79        mNextExpectedSeqNoValid = true;
80        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
81    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
82        ALOGV("Not the sequence number I expected");
83
84        return WRONG_SEQUENCE_NUMBER;
85    }
86
87    // hexdump(buffer->data(), buffer->size());
88
89    if ((buffer->size() % 188) > 0) {
90        queue->erase(queue->begin());
91        ++mNextExpectedSeqNo;
92
93        ALOGV("Not a multiple of transport packet size.");
94
95        return MALFORMED_PACKET;
96    }
97
98    sp<AMessage> msg = mNotifyMsg->dup();
99    msg->setBuffer("access-unit", buffer);
100    msg->post();
101
102    queue->erase(queue->begin());
103    ++mNextExpectedSeqNo;
104
105    return OK;
106}
107
108void AMPEG2TSAssembler::packetLost() {
109    CHECK(mNextExpectedSeqNoValid);
110    ++mNextExpectedSeqNo;
111}
112
113void AMPEG2TSAssembler::onByeReceived() {
114    sp<AMessage> msg = mNotifyMsg->dup();
115    msg->setInt32("eos", true);
116    msg->post();
117}
118
119}  // namespace android
120
121
122