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 
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 
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 
99 class WebmFrameSourceThread : public WebmFrameThread {
100 public:
101     WebmFrameSourceThread(int type, LinkedBlockingQueue<const sp<WebmFrame> >& sink);
102     virtual int64_t getDurationUs() = 0;
103 protected:
104     const int mType;
105     LinkedBlockingQueue<const sp<WebmFrame> >& mSink;
106 
107     friend class WebmFrameSinkThread;
108 };
109 
110 //=================================================================================================
111 
112 class WebmFrameEmptySourceThread : public WebmFrameSourceThread {
113 public:
WebmFrameEmptySourceThread(int type,LinkedBlockingQueue<const sp<WebmFrame>> & sink)114     WebmFrameEmptySourceThread(int type, LinkedBlockingQueue<const sp<WebmFrame> >& sink)
115         : WebmFrameSourceThread(type, sink) {
116     }
run()117     void run() { mSink.push(WebmFrame::EOS); }
getDurationUs()118     int64_t getDurationUs() { return 0; }
119 };
120 
121 //=================================================================================================
122 
123 class WebmFrameMediaSourceThread: public WebmFrameSourceThread {
124 public:
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();
getDurationUs()140     int64_t getDurationUs() {
141         return mTrackDurationUs;
142     }
143 
144 private:
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