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 WEBMWRITER_H_
18 #define WEBMWRITER_H_
19 
20 #include "WebmConstants.h"
21 #include "WebmFrameThread.h"
22 #include "LinkedBlockingQueue.h"
23 
24 #include <media/MediaSource.h>
25 #include <media/stagefright/MediaWriter.h>
26 
27 #include <utils/Errors.h>
28 #include <utils/Mutex.h>
29 #include <utils/StrongPointer.h>
30 
31 #include <stdint.h>
32 
33 using namespace webm;
34 
35 namespace android {
36 
37 class WebmWriter : public MediaWriter {
38 public:
39     explicit WebmWriter(int fd);
~WebmWriter()40     ~WebmWriter() { reset(); }
41 
42 
43     virtual status_t addSource(const sp<MediaSource> &source);
44     virtual status_t start(MetaData *param = NULL);
45     virtual status_t stop();
46     virtual status_t pause();
47     virtual bool reachedEOS();
48 
setStartTimeOffsetMs(int ms)49     virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
getStartTimeOffsetMs()50     virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
51 
52 private:
53     int mFd;
54     status_t mInitCheck;
55 
56     uint64_t mTimeCodeScale;
57     int64_t mStartTimestampUs;
58     int32_t mStartTimeOffsetMs;
59 
60     uint64_t mSegmentOffset;
61     uint64_t mSegmentDataStart;
62     uint64_t mInfoOffset;
63     uint64_t mInfoSize;
64     uint64_t mTracksOffset;
65     uint64_t mCuesOffset;
66 
67     bool mPaused;
68     bool mStarted;
69     bool mIsFileSizeLimitExplicitlyRequested;
70     bool mIsRealTimeRecording;
71     bool mStreamableFile;
72     uint64_t mEstimatedCuesSize;
73 
74     Mutex mLock;
75     List<sp<WebmElement> > mCuePoints;
76 
77     enum {
78         kAudioIndex     =  0,
79         kVideoIndex     =  1,
80         kMaxStreams     =  2,
81     };
82 
83     struct WebmStream {
84         int mType;
85         const char *mName;
86         sp<WebmElement> (*mMakeTrack)(const sp<MetaData>&);
87 
88         sp<MediaSource> mSource;
89         sp<WebmElement> mTrackEntry;
90         sp<WebmFrameSourceThread> mThread;
91         LinkedBlockingQueue<const sp<WebmFrame> > mSink;
92 
WebmStreamWebmStream93         WebmStream()
94             : mType(kInvalidType),
95               mName("Invalid"),
96               mMakeTrack(NULL) {
97         }
98 
WebmStreamWebmStream99         WebmStream(int type, const char *name, sp<WebmElement> (*makeTrack)(const sp<MetaData>&))
100             : mType(type),
101               mName(name),
102               mMakeTrack(makeTrack) {
103         }
104 
105         WebmStream &operator=(const WebmStream &other) {
106             mType = other.mType;
107             mName = other.mName;
108             mMakeTrack = other.mMakeTrack;
109             return *this;
110         }
111     };
112     WebmStream mStreams[kMaxStreams];
113     Vector<sp<WebmElement>> mStreamsInOrder;
114 
115     sp<WebmFrameSinkThread> mSinkThread;
116 
117     size_t numTracks();
118     uint64_t estimateCuesSize(int32_t bitRate);
119     void initStream(size_t idx);
120     void release();
121     status_t reset();
122 
123     static sp<WebmElement> videoTrack(const sp<MetaData>& md);
124     static sp<WebmElement> audioTrack(const sp<MetaData>& md);
125 
126     DISALLOW_EVIL_CONSTRUCTORS(WebmWriter);
127 };
128 
129 } /* namespace android */
130 #endif /* WEBMWRITER_H_ */
131