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 /** 52 * Creates the muxer for a given output format. 53 * @param fd : file descriptor of the output file. 54 * @param format : output format of the muxer. e.g.: webm/mp4/ogg 55 * @return writer's object or nullptr if error. 56 */ 57 static MediaMuxer* create(int fd, OutputFormat format); 58 59 virtual ~MediaMuxer(); 60 61 /** 62 * Add a track with its format information. This should be 63 * called before start(). 64 * @param format the track's format. 65 * @return the track's index or negative number if error. 66 */ 67 ssize_t addTrack(const sp<AMessage> &format); 68 69 /** 70 * Start muxing. Make sure all the tracks have been added before 71 * calling this. 72 */ 73 status_t start(); 74 75 /** 76 * Set the orientation hint. 77 * @param degrees The rotation degrees. It has to be either 0, 78 * 90, 180 or 270. 79 * @return OK if no error. 80 */ 81 status_t setOrientationHint(int degrees); 82 83 /** 84 * Set the location. 85 * @param latitude The latitude in degree x 1000. Its value must be in the range 86 * [-900000, 900000]. 87 * @param longitude The longitude in degree x 1000. Its value must be in the range 88 * [-1800000, 1800000]. 89 * @return OK if no error. 90 */ 91 status_t setLocation(int latitude, int longitude); 92 93 /** 94 * Stop muxing. 95 * This method is a blocking call. Depending on how 96 * much data is bufferred internally, the time needed for stopping 97 * the muxer may be time consuming. UI thread is 98 * not recommended for launching this call. 99 * @return OK if no error. 100 */ 101 status_t stop(); 102 103 /** 104 * Send a sample buffer for muxing. 105 * The buffer can be reused once this method returns. Typically, 106 * this function won't be blocked for very long, and thus there 107 * is no need to use a separate thread calling this method to 108 * push a buffer. 109 * @param buffer the incoming sample buffer. 110 * @param trackIndex the buffer's track index number. 111 * @param timeUs the buffer's time stamp. 112 * @param flags the only supported flag for now is 113 * MediaCodec::BUFFER_FLAG_SYNCFRAME. 114 * @return OK if no error. 115 */ 116 status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex, 117 int64_t timeUs, uint32_t flags) ; 118 119 /** 120 * Gets the number of tracks added successfully. Should be called in 121 * INITIALIZED(after constructor) or STARTED(after start()) state. 122 * @return the number of tracks or -1 in wrong state. 123 */ 124 ssize_t getTrackCount(); 125 126 /** 127 * Gets the format of the track by their index. 128 * @param idx : index of the track whose format is wanted. 129 * @return smart pointer to AMessage containing the format details. 130 */ 131 sp<AMessage> getTrackFormat(size_t idx); 132 133 private: 134 // Construct the muxer with the file descriptor. Note that the MediaMuxer 135 // will close this file at stop(). 136 // This constructor is made private to ensure that MediaMuxer::create() is used instead. 137 MediaMuxer(int fd, OutputFormat format); 138 139 const OutputFormat mFormat; 140 sp<MediaWriter> mWriter; 141 Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter. 142 Vector< sp<AMessage> > mFormatList; // Format of each track. 143 sp<MetaData> mFileMeta; // Metadata for the whole file. 144 Mutex mMuxerLock; 145 146 enum State { 147 UNINITIALIZED, 148 INITIALIZED, 149 STARTED, 150 STOPPED 151 }; 152 State mState; 153 154 DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer); 155 }; 156 157 } // namespace android 158 159 #endif // MEDIA_MUXER_H_ 160 161