1 /*
2  * Copyright 2013, 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 MEDIA_MUXER_H_
18 #define MEDIA_MUXER_H_
19 
20 #include <utils/Errors.h>
21 #include <utils/RefBase.h>
22 #include <utils/Vector.h>
23 #include <utils/threads.h>
24 
25 #include <map>
26 #include <mutex>
27 #include <vector>
28 
29 #include "media/stagefright/foundation/ABase.h"
30 #include "MediaMuxerBase.h"
31 
32 namespace android {
33 
34 struct ABuffer;
35 struct AMessage;
36 struct MediaAdapter;
37 class MediaBuffer;
38 struct MediaSource;
39 class MetaData;
40 struct MediaWriter;
41 struct NuMediaExtractor;
42 
43 // MediaMuxer is used to mux multiple tracks into a video. Currently, we only
44 // support a mp4 file as the output.
45 // The expected calling order of the functions is:
46 // Constructor -> addTrack+ -> start -> writeSampleData+ -> stop
47 // If muxing operation need to be cancelled, the app is responsible for
48 // deleting the output file after stop.
49 struct MediaMuxer : public MediaMuxerBase {
50 public:
51     // Construct the muxer with the file descriptor. Note that the MediaMuxer
52     // will close this file at stop().
53     MediaMuxer(int fd, OutputFormat format);
54 
55     virtual ~MediaMuxer();
56 
57     /**
58      * Add a track with its format information. This should be
59      * called before start().
60      * @param format the track's format.
61      * @return the track's index or negative number if error.
62      */
63     ssize_t addTrack(const sp<AMessage> &format);
64 
65     /**
66      * Start muxing. Make sure all the tracks have been added before
67      * calling this.
68      */
69     status_t start();
70 
71     /**
72      * Set the orientation hint.
73      * @param degrees The rotation degrees. It has to be either 0,
74      *                90, 180 or 270.
75      * @return OK if no error.
76      */
77     status_t setOrientationHint(int degrees);
78 
79     /**
80      * Set the location.
81      * @param latitude The latitude in degree x 1000. Its value must be in the range
82      * [-900000, 900000].
83      * @param longitude The longitude in degree x 1000. Its value must be in the range
84      * [-1800000, 1800000].
85      * @return OK if no error.
86      */
87     status_t setLocation(int latitude, int longitude);
88 
89     /**
90      * Stop muxing.
91      * This method is a blocking call. Depending on how
92      * much data is bufferred internally, the time needed for stopping
93      * the muxer may be time consuming. UI thread is
94      * not recommended for launching this call.
95      * @return OK if no error.
96      */
97     status_t stop();
98 
99     /**
100      * Send a sample buffer for muxing.
101      * The buffer can be reused once this method returns. Typically,
102      * this function won't be blocked for very long, and thus there
103      * is no need to use a separate thread calling this method to
104      * push a buffer.
105      * @param buffer the incoming sample buffer.
106      * @param trackIndex the buffer's track index number.
107      * @param timeUs the buffer's time stamp.
108      * @param flags the only supported flag for now is
109      *              MediaCodec::BUFFER_FLAG_SYNCFRAME.
110      * @return OK if no error.
111      */
112     status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex,
113                              int64_t timeUs, uint32_t flags) ;
114 
115     /**
116      * Gets the number of tracks added successfully.  Should be called in
117      * INITIALIZED(after constructor) or STARTED(after start()) state.
118      * @return the number of tracks or -1 in wrong state.
119      */
120     ssize_t getTrackCount();
121 
122     /**
123      * Gets the format of the track by their index.
124      * @param idx : index of the track whose format is wanted.
125      * @return smart pointer to AMessage containing the format details.
126      */
127     sp<AMessage> getTrackFormat(size_t idx);
128 
129 private:
130     const OutputFormat mFormat;
131     sp<MediaWriter> mWriter;
132     Vector< sp<MediaAdapter> > mTrackList;  // Each track has its MediaAdapter.
133     Vector< sp<AMessage> > mFormatList; // Format of each track.
134     sp<MetaData> mFileMeta;  // Metadata for the whole file.
135     Mutex mMuxerLock;
136 
137     enum State {
138         UNINITIALIZED,
139         INITIALIZED,
140         STARTED,
141         STOPPED
142     };
143     State mState;
144 
145     DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer);
146 };
147 
148 }  // namespace android
149 
150 #endif  // MEDIA_MUXER_H_
151 
152