summaryrefslogtreecommitdiffstats
path: root/include/media/stagefright/MediaMuxer.h
blob: fa855a8c37722d46adbb070a8f996df710b0e54b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright 2013, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MEDIA_MUXER_H_
#define MEDIA_MUXER_H_

#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
#include <utils/threads.h>

#include "foundation/ABase.h"

namespace android {

struct ABuffer;
struct AMessage;
struct MediaAdapter;
class MediaBuffer;
struct MediaSource;
class MetaData;
struct MediaWriter;

// MediaMuxer is used to mux multiple tracks into a video. Currently, we only
// support a mp4 file as the output.
// The expected calling order of the functions is:
// Constructor -> addTrack+ -> start -> writeSampleData+ -> stop
// If muxing operation need to be cancelled, the app is responsible for
// deleting the output file after stop.
struct MediaMuxer : public RefBase {
public:
    // Please update media/java/android/media/MediaMuxer.java if the
    // OutputFormat is updated.
    enum OutputFormat {
        OUTPUT_FORMAT_MPEG_4 = 0,
        OUTPUT_FORMAT_WEBM   = 1,
        OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
    };

    // Construct the muxer with the file descriptor. Note that the MediaMuxer
    // will close this file at stop().
    MediaMuxer(int fd, OutputFormat format);

    virtual ~MediaMuxer();

    /**
     * Add a track with its format information. This should be
     * called before start().
     * @param format the track's format.
     * @return the track's index or negative number if error.
     */
    ssize_t addTrack(const sp<AMessage> &format);

    /**
     * Start muxing. Make sure all the tracks have been added before
     * calling this.
     */
    status_t start();

    /**
     * Set the orientation hint.
     * @param degrees The rotation degrees. It has to be either 0,
     *                90, 180 or 270.
     * @return OK if no error.
     */
    status_t setOrientationHint(int degrees);

    /**
     * Set the location.
     * @param latitude The latitude in degree x 1000. Its value must be in the range
     * [-900000, 900000].
     * @param longitude The longitude in degree x 1000. Its value must be in the range
     * [-1800000, 1800000].
     * @return OK if no error.
     */
    status_t setLocation(int latitude, int longitude);

    /**
     * Stop muxing.
     * This method is a blocking call. Depending on how
     * much data is bufferred internally, the time needed for stopping
     * the muxer may be time consuming. UI thread is
     * not recommended for launching this call.
     * @return OK if no error.
     */
    status_t stop();

    /**
     * Send a sample buffer for muxing.
     * The buffer can be reused once this method returns. Typically,
     * this function won't be blocked for very long, and thus there
     * is no need to use a separate thread calling this method to
     * push a buffer.
     * @param buffer the incoming sample buffer.
     * @param trackIndex the buffer's track index number.
     * @param timeUs the buffer's time stamp.
     * @param flags the only supported flag for now is
     *              MediaCodec::BUFFER_FLAG_SYNCFRAME.
     * @return OK if no error.
     */
    status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex,
                             int64_t timeUs, uint32_t flags) ;

private:
    const OutputFormat mFormat;
    sp<MediaWriter> mWriter;
    Vector< sp<MediaAdapter> > mTrackList;  // Each track has its MediaAdapter.
    sp<MetaData> mFileMeta;  // Metadata for the whole file.

    Mutex mMuxerLock;

    enum State {
        UNINITIALIZED,
        INITIALIZED,
        STARTED,
        STOPPED
    };
    State mState;

    DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer);
};

}  // namespace android

#endif  // MEDIA_MUXER_H_