1343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih/*
2343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * Copyright (C) 2014 The Android Open Source Project
3343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *
4343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * Licensed under the Apache License, Version 2.0 (the "License");
5343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * you may not use this file except in compliance with the License.
6343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * You may obtain a copy of the License at
7343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *
8343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *      http://www.apache.org/licenses/LICENSE-2.0
9343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih *
10343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * Unless required by applicable law or agreed to in writing, software
11343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * distributed under the License is distributed on an "AS IS" BASIS,
12343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * See the License for the specific language governing permissions and
14343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih * limitations under the License.
15343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih */
16343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
17343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#ifndef WEBMWRITER_H_
18343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#define WEBMWRITER_H_
19343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
20343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include "WebmConstants.h"
21343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include "WebmFrameThread.h"
22343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include "LinkedBlockingQueue.h"
23343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
24343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <media/stagefright/MediaSource.h>
25343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <media/stagefright/MediaWriter.h>
26343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
27343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <utils/Errors.h>
28343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <utils/Mutex.h>
29343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <utils/StrongPointer.h>
30343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
31343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#include <stdint.h>
32343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
33343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihusing namespace webm;
34343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
35343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihnamespace android {
36343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
37343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihclass WebmWriter : public MediaWriter {
38343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihpublic:
39343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    WebmWriter(int fd);
40343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ~WebmWriter() { reset(); }
41343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
42343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
43b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    virtual status_t addSource(const sp<IMediaSource> &source);
44d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t start(MetaData *param = NULL);
45d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t stop();
46d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t pause();
47d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual bool reachedEOS();
48d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih
49d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
50d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
51343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
52343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihprivate:
53343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int mFd;
54343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    status_t mInitCheck;
55343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
56343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mTimeCodeScale;
57343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int64_t mStartTimestampUs;
58343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int32_t mStartTimeOffsetMs;
59343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
60343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mSegmentOffset;
61343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mSegmentDataStart;
62343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mInfoOffset;
63343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mInfoSize;
64343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mTracksOffset;
65343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mCuesOffset;
66343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
67343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mPaused;
68343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mStarted;
69343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mIsFileSizeLimitExplicitlyRequested;
70343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mIsRealTimeRecording;
71343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mStreamableFile;
72343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mEstimatedCuesSize;
73343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
74343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    Mutex mLock;
75343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > mCuePoints;
76343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
77343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    enum {
78343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        kAudioIndex     =  0,
79343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        kVideoIndex     =  1,
80343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        kMaxStreams     =  2,
81343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    };
82343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
83343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    struct WebmStream {
84343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int mType;
85343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const char *mName;
86343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmElement> (*mMakeTrack)(const sp<MetaData>&);
87343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
88b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        sp<IMediaSource> mSource;
89343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmElement> mTrackEntry;
90343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmFrameSourceThread> mThread;
91343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        LinkedBlockingQueue<const sp<WebmFrame> > mSink;
92343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
93343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmStream()
94343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            : mType(kInvalidType),
95343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mName("Invalid"),
96343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mMakeTrack(NULL) {
97343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        }
98343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
99343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmStream(int type, const char *name, sp<WebmElement> (*makeTrack)(const sp<MetaData>&))
100343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            : mType(type),
101343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mName(name),
102343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mMakeTrack(makeTrack) {
103343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        }
104343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
105343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmStream &operator=(const WebmStream &other) {
106343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            mType = other.mType;
107343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            mName = other.mName;
108343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            mMakeTrack = other.mMakeTrack;
109343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            return *this;
110343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        }
111343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    };
112343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    WebmStream mStreams[kMaxStreams];
1132bae6deec84016b9caaffcb536534820c47b12d2Lajos Molnar    Vector<sp<WebmElement>> mStreamsInOrder;
114343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
115343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    sp<WebmFrameSinkThread> mSinkThread;
116343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
117343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    size_t numTracks();
118343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t estimateCuesSize(int32_t bitRate);
119343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    void initStream(size_t idx);
120343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    void release();
121343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    status_t reset();
122343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
123343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    static sp<WebmElement> videoTrack(const sp<MetaData>& md);
124343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    static sp<WebmElement> audioTrack(const sp<MetaData>& md);
125343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
126343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    DISALLOW_EVIL_CONSTRUCTORS(WebmWriter);
127343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih};
128343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
129343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih} /* namespace android */
130343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih#endif /* WEBMWRITER_H_ */
131