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#ifndef ANOTHER_PACKET_SOURCE_H_
18
19#define ANOTHER_PACKET_SOURCE_H_
20
21#include <media/stagefright/foundation/ABase.h>
22#include <media/stagefright/MediaSource.h>
23#include <utils/threads.h>
24#include <utils/List.h>
25
26#include "ATSParser.h"
27
28namespace android {
29
30struct ABuffer;
31
32struct AnotherPacketSource : public MediaSource {
33    explicit AnotherPacketSource(const sp<MetaData> &meta);
34
35    void setFormat(const sp<MetaData> &meta);
36
37    virtual status_t start(MetaData *params = NULL);
38    virtual status_t stop();
39    virtual sp<MetaData> getFormat();
40
41    virtual status_t read(
42            MediaBuffer **buffer, const ReadOptions *options = NULL);
43
44    void clear();
45
46    // Returns true if we have any packets including discontinuities
47    bool hasBufferAvailable(status_t *finalResult);
48
49    // Returns true if we have packets that's not discontinuities
50    bool hasDataBufferAvailable(status_t *finalResult);
51
52    // Returns the number of available buffers. finalResult is always OK
53    // if this method returns non-0, or the final result if it returns 0.
54    size_t getAvailableBufferCount(status_t *finalResult);
55
56    // Returns the difference between the last and the first queued
57    // presentation timestamps since the last discontinuity (if any).
58    int64_t getBufferedDurationUs(status_t *finalResult);
59
60    // Returns the difference between the two largest timestamps queued
61    int64_t getEstimatedBufferDurationUs();
62
63    status_t nextBufferTime(int64_t *timeUs);
64
65    void queueAccessUnit(const sp<ABuffer> &buffer);
66
67    void queueDiscontinuity(
68            ATSParser::DiscontinuityType type,
69            const sp<AMessage> &extra,
70            bool discard);
71
72    void signalEOS(status_t result);
73
74    status_t dequeueAccessUnit(sp<ABuffer> *buffer);
75    void requeueAccessUnit(const sp<ABuffer> &buffer);
76
77    bool isFinished(int64_t duration) const;
78
79    void enable(bool enable);
80
81    sp<AMessage> getLatestEnqueuedMeta();
82    sp<AMessage> getLatestDequeuedMeta();
83    sp<AMessage> getMetaAfterLastDequeued(int64_t delayUs);
84
85    void trimBuffersAfterMeta(const sp<AMessage> &meta);
86    sp<AMessage> trimBuffersBeforeMeta(const sp<AMessage> &meta);
87
88protected:
89    virtual ~AnotherPacketSource();
90
91private:
92
93    struct DiscontinuitySegment {
94        int64_t mMaxDequeTimeUs, mMaxEnqueTimeUs;
95        DiscontinuitySegment()
96            : mMaxDequeTimeUs(-1),
97              mMaxEnqueTimeUs(-1) {
98        };
99
100        void clear() {
101            mMaxDequeTimeUs = mMaxEnqueTimeUs = -1;
102        }
103    };
104
105    // Discontinuity segments are consecutive access units between
106    // discontinuity markers. There should always be at least _ONE_
107    // discontinuity segment, hence the various CHECKs in
108    // AnotherPacketSource.cpp for non-empty()-ness.
109    List<DiscontinuitySegment> mDiscontinuitySegments;
110
111    Mutex mLock;
112    Condition mCondition;
113
114    bool mIsAudio;
115    bool mIsVideo;
116    bool mEnabled;
117    sp<MetaData> mFormat;
118    int64_t mLastQueuedTimeUs;
119    int64_t mEstimatedBufferDurationUs;
120    List<sp<ABuffer> > mBuffers;
121    status_t mEOSResult;
122    sp<AMessage> mLatestEnqueuedMeta;
123    sp<AMessage> mLatestDequeuedMeta;
124
125    bool wasFormatChange(int32_t discontinuityType) const;
126
127    DISALLOW_EVIL_CONSTRUCTORS(AnotherPacketSource);
128};
129
130
131}  // namespace android
132
133#endif  // ANOTHER_PACKET_SOURCE_H_
134