1/*
2 * Copyright (C) 2014 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 WEBMFRAMETHREAD_H_
18#define WEBMFRAMETHREAD_H_
19
20#include "WebmFrame.h"
21#include "LinkedBlockingQueue.h"
22
23#include <media/stagefright/FileSource.h>
24#include <media/stagefright/MediaSource.h>
25
26#include <utils/List.h>
27#include <utils/Errors.h>
28
29#include <pthread.h>
30
31namespace android {
32
33class WebmFrameThread : public LightRefBase<WebmFrameThread> {
34public:
35    virtual void run() = 0;
36    virtual bool running() { return false; }
37    virtual status_t start();
38    virtual status_t pause() { return OK; }
39    virtual status_t resume() { return OK; }
40    virtual status_t stop();
41    virtual ~WebmFrameThread() { stop(); }
42    static void *wrap(void *arg);
43
44protected:
45    WebmFrameThread()
46        : mThread(0) {
47    }
48
49private:
50    pthread_t mThread;
51    DISALLOW_EVIL_CONSTRUCTORS(WebmFrameThread);
52};
53
54//=================================================================================================
55
56class WebmFrameSourceThread;
57class WebmFrameSinkThread : public WebmFrameThread {
58public:
59    WebmFrameSinkThread(
60            const int& fd,
61            const uint64_t& off,
62            sp<WebmFrameSourceThread> videoThread,
63            sp<WebmFrameSourceThread> audioThread,
64            List<sp<WebmElement> >& cues);
65
66    WebmFrameSinkThread(
67            const int& fd,
68            const uint64_t& off,
69            LinkedBlockingQueue<const sp<WebmFrame> >& videoSource,
70            LinkedBlockingQueue<const sp<WebmFrame> >& audioSource,
71            List<sp<WebmElement> >& cues);
72
73    void run();
74    bool running() {
75        return !mDone;
76    }
77    status_t start();
78    status_t stop();
79
80private:
81    const int& mFd;
82    const uint64_t& mSegmentDataStart;
83    LinkedBlockingQueue<const sp<WebmFrame> >& mVideoFrames;
84    LinkedBlockingQueue<const sp<WebmFrame> >& mAudioFrames;
85    List<sp<WebmElement> >& mCues;
86
87    volatile bool mDone;
88
89    static void initCluster(
90            List<const sp<WebmFrame> >& frames,
91            uint64_t& clusterTimecodeL,
92            List<sp<WebmElement> >& children);
93    void writeCluster(List<sp<WebmElement> >& children);
94    void flushFrames(List<const sp<WebmFrame> >& frames, bool last);
95};
96
97//=================================================================================================
98
99class WebmFrameSourceThread : public WebmFrameThread {
100public:
101    WebmFrameSourceThread(int type, LinkedBlockingQueue<const sp<WebmFrame> >& sink);
102    virtual int64_t getDurationUs() = 0;
103protected:
104    const int mType;
105    LinkedBlockingQueue<const sp<WebmFrame> >& mSink;
106
107    friend class WebmFrameSinkThread;
108};
109
110//=================================================================================================
111
112class WebmFrameEmptySourceThread : public WebmFrameSourceThread {
113public:
114    WebmFrameEmptySourceThread(int type, LinkedBlockingQueue<const sp<WebmFrame> >& sink)
115        : WebmFrameSourceThread(type, sink) {
116    }
117    void run() { mSink.push(WebmFrame::EOS); }
118    int64_t getDurationUs() { return 0; }
119};
120
121//=================================================================================================
122
123class WebmFrameMediaSourceThread: public WebmFrameSourceThread {
124public:
125    WebmFrameMediaSourceThread(
126            const sp<MediaSource>& source,
127            int type,
128            LinkedBlockingQueue<const sp<WebmFrame> >& sink,
129            uint64_t timeCodeScale,
130            int64_t startTimeRealUs,
131            int32_t startTimeOffsetMs,
132            int numPeers,
133            bool realTimeRecording);
134
135    void run();
136    status_t start();
137    status_t resume();
138    status_t pause();
139    status_t stop();
140    int64_t getDurationUs() {
141        return mTrackDurationUs;
142    }
143
144private:
145    const sp<MediaSource> mSource;
146    const uint64_t mTimeCodeScale;
147    uint64_t mStartTimeUs;
148
149    volatile bool mDone;
150    volatile bool mPaused;
151    volatile bool mResumed;
152    volatile bool mStarted;
153    volatile bool mReachedEOS;
154    int64_t mTrackDurationUs;
155
156    void clearFlags();
157};
158} /* namespace android */
159
160#endif /* WEBMFRAMETHREAD_H_ */
161