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
33using namespace webm;
34
35namespace android {
36
37class WebmWriter : public MediaWriter {
38public:
39    WebmWriter(int fd);
40    WebmWriter(const char *filename);
41    ~WebmWriter() { reset(); }
42
43
44    virtual status_t addSource(const sp<MediaSource> &source);
45    virtual status_t start(MetaData *param = NULL);
46    virtual status_t stop();
47    virtual status_t pause();
48    virtual bool reachedEOS();
49
50    virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
51    virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
52
53private:
54    int mFd;
55    status_t mInitCheck;
56
57    uint64_t mTimeCodeScale;
58    int64_t mStartTimestampUs;
59    int32_t mStartTimeOffsetMs;
60
61    uint64_t mSegmentOffset;
62    uint64_t mSegmentDataStart;
63    uint64_t mInfoOffset;
64    uint64_t mInfoSize;
65    uint64_t mTracksOffset;
66    uint64_t mCuesOffset;
67
68    bool mPaused;
69    bool mStarted;
70    bool mIsFileSizeLimitExplicitlyRequested;
71    bool mIsRealTimeRecording;
72    bool mStreamableFile;
73    uint64_t mEstimatedCuesSize;
74
75    Mutex mLock;
76    List<sp<WebmElement> > mCuePoints;
77
78    enum {
79        kAudioIndex     =  0,
80        kVideoIndex     =  1,
81        kMaxStreams     =  2,
82    };
83
84    struct WebmStream {
85        int mType;
86        const char *mName;
87        sp<WebmElement> (*mMakeTrack)(const sp<MetaData>&);
88
89        sp<MediaSource> mSource;
90        sp<WebmElement> mTrackEntry;
91        sp<WebmFrameSourceThread> mThread;
92        LinkedBlockingQueue<const sp<WebmFrame> > mSink;
93
94        WebmStream()
95            : mType(kInvalidType),
96              mName("Invalid"),
97              mMakeTrack(NULL) {
98        }
99
100        WebmStream(int type, const char *name, sp<WebmElement> (*makeTrack)(const sp<MetaData>&))
101            : mType(type),
102              mName(name),
103              mMakeTrack(makeTrack) {
104        }
105
106        WebmStream &operator=(const WebmStream &other) {
107            mType = other.mType;
108            mName = other.mName;
109            mMakeTrack = other.mMakeTrack;
110            return *this;
111        }
112    };
113    WebmStream mStreams[kMaxStreams];
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