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(const char *filename);
41343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    ~WebmWriter() { reset(); }
42343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
43343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
44d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t addSource(const sp<MediaSource> &source);
45d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t start(MetaData *param = NULL);
46d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t stop();
47d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual status_t pause();
48d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual bool reachedEOS();
49d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih
50d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
51d8cf55d878edddfc36bb821a95b88dfb2453c2c3Robert Shih    virtual int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
52343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
53343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihprivate:
54343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int mFd;
55343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    status_t mInitCheck;
56343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
57343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mTimeCodeScale;
58343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int64_t mStartTimestampUs;
59343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    int32_t mStartTimeOffsetMs;
60343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
61343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mSegmentOffset;
62343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mSegmentDataStart;
63343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mInfoOffset;
64343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mInfoSize;
65343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mTracksOffset;
66343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mCuesOffset;
67343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
68343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mPaused;
69343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mStarted;
70343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mIsFileSizeLimitExplicitlyRequested;
71343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mIsRealTimeRecording;
72343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    bool mStreamableFile;
73343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    uint64_t mEstimatedCuesSize;
74343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
75343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    Mutex mLock;
76343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    List<sp<WebmElement> > mCuePoints;
77343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
78343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    enum {
79343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        kAudioIndex     =  0,
80343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        kVideoIndex     =  1,
81343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        kMaxStreams     =  2,
82343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    };
83343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
84343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    struct WebmStream {
85343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        int mType;
86343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        const char *mName;
87343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmElement> (*mMakeTrack)(const sp<MetaData>&);
88343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
89343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<MediaSource> mSource;
90343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmElement> mTrackEntry;
91343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        sp<WebmFrameSourceThread> mThread;
92343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        LinkedBlockingQueue<const sp<WebmFrame> > mSink;
93343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
94343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmStream()
95343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            : mType(kInvalidType),
96343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mName("Invalid"),
97343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mMakeTrack(NULL) {
98343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        }
99343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
100343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmStream(int type, const char *name, sp<WebmElement> (*makeTrack)(const sp<MetaData>&))
101343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            : mType(type),
102343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mName(name),
103343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih              mMakeTrack(makeTrack) {
104343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        }
105343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih
106343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        WebmStream &operator=(const WebmStream &other) {
107343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            mType = other.mType;
108343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            mName = other.mName;
109343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            mMakeTrack = other.mMakeTrack;
110343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih            return *this;
111343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        }
112343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    };
113343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    WebmStream mStreams[kMaxStreams];
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