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/stagefright/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     // Returns true if the file descriptor is opened using a mode
40     // which is compatible with WebmWriter.
41     // Note that this overloads that method in the base class.
42     static bool isFdOpenModeValid(int fd);
43     // Returns true if the timestamp is valid which is compatible with the WebmWriter.
44     // Note that this overloads that method in the base class.
45     bool isSampleMetadataValid(size_t trackIndex, int64_t timeUs);
46     explicit WebmWriter(int fd);
~WebmWriter()47     ~WebmWriter() { reset(); }
48 
49 
50     virtual status_t addSource(const sp<MediaSource> &source);
51     virtual status_t start(MetaData *param = NULL);
52     virtual status_t stop();
53     virtual status_t pause();
54     virtual bool reachedEOS();
55 
setStartTimeOffsetMs(int ms)56     virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
getStartTimeOffsetMs()57     virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
58 
59 private:
60     int mFd;
61     status_t mInitCheck;
62 
63     uint64_t mTimeCodeScale;
64     int64_t mStartTimestampUs;
65     int32_t mStartTimeOffsetMs;
66 
67     uint64_t mSegmentOffset;
68     uint64_t mSegmentDataStart;
69     uint64_t mInfoOffset;
70     uint64_t mInfoSize;
71     uint64_t mTracksOffset;
72     uint64_t mCuesOffset;
73     std::map<size_t, int64_t> mLastTimestampUsByTrackIndex;
74 
75     bool mPaused;
76     bool mStarted;
77     bool mIsFileSizeLimitExplicitlyRequested;
78     bool mIsRealTimeRecording;
79     bool mStreamableFile;
80     uint64_t mEstimatedCuesSize;
81 
82     Mutex mLock;
83     List<sp<WebmElement> > mCuePoints;
84 
85     enum {
86         kAudioIndex     =  0,
87         kVideoIndex     =  1,
88         kMaxStreams     =  2,
89     };
90 
91     struct WebmStream {
92         int mType;
93         const char *mName;
94         sp<WebmElement> (*mMakeTrack)(const sp<MetaData>&);
95 
96         sp<MediaSource> mSource;
97         sp<WebmElement> mTrackEntry;
98         sp<WebmFrameSourceThread> mThread;
99         LinkedBlockingQueue<const sp<WebmFrame> > mSink;
100 
WebmStreamWebmStream101         WebmStream()
102             : mType(kInvalidType),
103               mName("Invalid"),
104               mMakeTrack(NULL) {
105         }
106 
WebmStreamWebmStream107         WebmStream(int type, const char *name, sp<WebmElement> (*makeTrack)(const sp<MetaData>&))
108             : mType(type),
109               mName(name),
110               mMakeTrack(makeTrack) {
111         }
112 
113         WebmStream &operator=(const WebmStream &other) {
114             mType = other.mType;
115             mName = other.mName;
116             mMakeTrack = other.mMakeTrack;
117             return *this;
118         }
119     };
120     WebmStream mStreams[kMaxStreams];
121     Vector<sp<WebmElement>> mStreamsInOrder;
122 
123     sp<WebmFrameSinkThread> mSinkThread;
124 
125     size_t numTracks();
126     uint64_t estimateCuesSize(int32_t bitRate);
127     void initStream(size_t idx);
128     void release();
129     status_t reset();
130 
131     static sp<WebmElement> videoTrack(const sp<MetaData>& md);
132     static sp<WebmElement> audioTrack(const sp<MetaData>& md);
133 
134     DISALLOW_EVIL_CONSTRUCTORS(WebmWriter);
135 };
136 
137 } /* namespace android */
138 #endif /* WEBMWRITER_H_ */
139