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