16269d53cce5c1c9350565d3d72d92116594260cbztenghui/*
26269d53cce5c1c9350565d3d72d92116594260cbztenghui * Copyright 2013, The Android Open Source Project
36269d53cce5c1c9350565d3d72d92116594260cbztenghui *
46269d53cce5c1c9350565d3d72d92116594260cbztenghui * Licensed under the Apache License, Version 2.0 (the "License");
56269d53cce5c1c9350565d3d72d92116594260cbztenghui * you may not use this file except in compliance with the License.
66269d53cce5c1c9350565d3d72d92116594260cbztenghui * You may obtain a copy of the License at
76269d53cce5c1c9350565d3d72d92116594260cbztenghui *
86269d53cce5c1c9350565d3d72d92116594260cbztenghui *     http://www.apache.org/licenses/LICENSE-2.0
96269d53cce5c1c9350565d3d72d92116594260cbztenghui *
106269d53cce5c1c9350565d3d72d92116594260cbztenghui * Unless required by applicable law or agreed to in writing, software
116269d53cce5c1c9350565d3d72d92116594260cbztenghui * distributed under the License is distributed on an "AS IS" BASIS,
126269d53cce5c1c9350565d3d72d92116594260cbztenghui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136269d53cce5c1c9350565d3d72d92116594260cbztenghui * See the License for the specific language governing permissions and
146269d53cce5c1c9350565d3d72d92116594260cbztenghui * limitations under the License.
156269d53cce5c1c9350565d3d72d92116594260cbztenghui */
166269d53cce5c1c9350565d3d72d92116594260cbztenghui
176269d53cce5c1c9350565d3d72d92116594260cbztenghui#ifndef MEDIA_MUXER_H_
186269d53cce5c1c9350565d3d72d92116594260cbztenghui#define MEDIA_MUXER_H_
196269d53cce5c1c9350565d3d72d92116594260cbztenghui
206269d53cce5c1c9350565d3d72d92116594260cbztenghui#include <utils/Errors.h>
216269d53cce5c1c9350565d3d72d92116594260cbztenghui#include <utils/RefBase.h>
226269d53cce5c1c9350565d3d72d92116594260cbztenghui#include <utils/Vector.h>
236269d53cce5c1c9350565d3d72d92116594260cbztenghui#include <utils/threads.h>
246269d53cce5c1c9350565d3d72d92116594260cbztenghui
256269d53cce5c1c9350565d3d72d92116594260cbztenghuinamespace android {
266269d53cce5c1c9350565d3d72d92116594260cbztenghui
276269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct ABuffer;
286269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct AMessage;
296269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct MediaAdapter;
306269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct MediaBuffer;
316269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct MediaSource;
326269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct MetaData;
33343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shihstruct MediaWriter;
346269d53cce5c1c9350565d3d72d92116594260cbztenghui
356269d53cce5c1c9350565d3d72d92116594260cbztenghui// MediaMuxer is used to mux multiple tracks into a video. Currently, we only
366269d53cce5c1c9350565d3d72d92116594260cbztenghui// support a mp4 file as the output.
376269d53cce5c1c9350565d3d72d92116594260cbztenghui// The expected calling order of the functions is:
386269d53cce5c1c9350565d3d72d92116594260cbztenghui// Constructor -> addTrack+ -> start -> writeSampleData+ -> stop
396269d53cce5c1c9350565d3d72d92116594260cbztenghui// If muxing operation need to be cancelled, the app is responsible for
406269d53cce5c1c9350565d3d72d92116594260cbztenghui// deleting the output file after stop.
416269d53cce5c1c9350565d3d72d92116594260cbztenghuistruct MediaMuxer : public RefBase {
426269d53cce5c1c9350565d3d72d92116594260cbztenghuipublic:
43afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui    // Please update media/java/android/media/MediaMuxer.java if the
44afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui    // OutputFormat is updated.
45afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui    enum OutputFormat {
46afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui        OUTPUT_FORMAT_MPEG_4 = 0,
47343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih        OUTPUT_FORMAT_WEBM   = 1,
48afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui        OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
49afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui    };
50afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui
516269d53cce5c1c9350565d3d72d92116594260cbztenghui    // Construct the muxer with the output file path.
52afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui    MediaMuxer(const char *path, OutputFormat format);
53afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui
546269d53cce5c1c9350565d3d72d92116594260cbztenghui    // Construct the muxer with the file descriptor. Note that the MediaMuxer
556269d53cce5c1c9350565d3d72d92116594260cbztenghui    // will close this file at stop().
56afde4e56566af19b36f1fe5e7aa7f226bf1703ddztenghui    MediaMuxer(int fd, OutputFormat format);
576269d53cce5c1c9350565d3d72d92116594260cbztenghui
586269d53cce5c1c9350565d3d72d92116594260cbztenghui    virtual ~MediaMuxer();
596269d53cce5c1c9350565d3d72d92116594260cbztenghui
606269d53cce5c1c9350565d3d72d92116594260cbztenghui    /**
616269d53cce5c1c9350565d3d72d92116594260cbztenghui     * Add a track with its format information. This should be
626269d53cce5c1c9350565d3d72d92116594260cbztenghui     * called before start().
636269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @param format the track's format.
646269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @return the track's index or negative number if error.
656269d53cce5c1c9350565d3d72d92116594260cbztenghui     */
666269d53cce5c1c9350565d3d72d92116594260cbztenghui    ssize_t addTrack(const sp<AMessage> &format);
676269d53cce5c1c9350565d3d72d92116594260cbztenghui
686269d53cce5c1c9350565d3d72d92116594260cbztenghui    /**
696269d53cce5c1c9350565d3d72d92116594260cbztenghui     * Start muxing. Make sure all the tracks have been added before
706269d53cce5c1c9350565d3d72d92116594260cbztenghui     * calling this.
716269d53cce5c1c9350565d3d72d92116594260cbztenghui     */
726269d53cce5c1c9350565d3d72d92116594260cbztenghui    status_t start();
736269d53cce5c1c9350565d3d72d92116594260cbztenghui
746269d53cce5c1c9350565d3d72d92116594260cbztenghui    /**
7511287471298193ff51ffb429686f5d63a84a621bztenghui     * Set the orientation hint.
7611287471298193ff51ffb429686f5d63a84a621bztenghui     * @param degrees The rotation degrees. It has to be either 0,
7711287471298193ff51ffb429686f5d63a84a621bztenghui     *                90, 180 or 270.
7811287471298193ff51ffb429686f5d63a84a621bztenghui     * @return OK if no error.
7911287471298193ff51ffb429686f5d63a84a621bztenghui     */
8011287471298193ff51ffb429686f5d63a84a621bztenghui    status_t setOrientationHint(int degrees);
8111287471298193ff51ffb429686f5d63a84a621bztenghui
8211287471298193ff51ffb429686f5d63a84a621bztenghui    /**
837f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     * Set the location.
847f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     * @param latitude The latitude in degree x 1000. Its value must be in the range
857f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     * [-900000, 900000].
867f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     * @param longitude The longitude in degree x 1000. Its value must be in the range
877f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     * [-1800000, 1800000].
887f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     * @return OK if no error.
897f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He     */
907f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He    status_t setLocation(int latitude, int longitude);
917f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He
927f9551f75eedb3e4e1fe8feaaba48d8080635fc4Zhijun He    /**
936269d53cce5c1c9350565d3d72d92116594260cbztenghui     * Stop muxing.
946269d53cce5c1c9350565d3d72d92116594260cbztenghui     * This method is a blocking call. Depending on how
956269d53cce5c1c9350565d3d72d92116594260cbztenghui     * much data is bufferred internally, the time needed for stopping
966269d53cce5c1c9350565d3d72d92116594260cbztenghui     * the muxer may be time consuming. UI thread is
976269d53cce5c1c9350565d3d72d92116594260cbztenghui     * not recommended for launching this call.
9811287471298193ff51ffb429686f5d63a84a621bztenghui     * @return OK if no error.
996269d53cce5c1c9350565d3d72d92116594260cbztenghui     */
1006269d53cce5c1c9350565d3d72d92116594260cbztenghui    status_t stop();
1016269d53cce5c1c9350565d3d72d92116594260cbztenghui
1026269d53cce5c1c9350565d3d72d92116594260cbztenghui    /**
1036269d53cce5c1c9350565d3d72d92116594260cbztenghui     * Send a sample buffer for muxing.
1046269d53cce5c1c9350565d3d72d92116594260cbztenghui     * The buffer can be reused once this method returns. Typically,
1056269d53cce5c1c9350565d3d72d92116594260cbztenghui     * this function won't be blocked for very long, and thus there
1066269d53cce5c1c9350565d3d72d92116594260cbztenghui     * is no need to use a separate thread calling this method to
1076269d53cce5c1c9350565d3d72d92116594260cbztenghui     * push a buffer.
1086269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @param buffer the incoming sample buffer.
1096269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @param trackIndex the buffer's track index number.
1106269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @param timeUs the buffer's time stamp.
1116269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @param flags the only supported flag for now is
1126269d53cce5c1c9350565d3d72d92116594260cbztenghui     *              MediaCodec::BUFFER_FLAG_SYNCFRAME.
1136269d53cce5c1c9350565d3d72d92116594260cbztenghui     * @return OK if no error.
1146269d53cce5c1c9350565d3d72d92116594260cbztenghui     */
1156269d53cce5c1c9350565d3d72d92116594260cbztenghui    status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex,
1166269d53cce5c1c9350565d3d72d92116594260cbztenghui                             int64_t timeUs, uint32_t flags) ;
1176269d53cce5c1c9350565d3d72d92116594260cbztenghui
1186269d53cce5c1c9350565d3d72d92116594260cbztenghuiprivate:
119343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    const OutputFormat mFormat;
120343947abc8b7c126f966fd32a0b18bff6c2cecd1Robert Shih    sp<MediaWriter> mWriter;
1216269d53cce5c1c9350565d3d72d92116594260cbztenghui    Vector< sp<MediaAdapter> > mTrackList;  // Each track has its MediaAdapter.
12211287471298193ff51ffb429686f5d63a84a621bztenghui    sp<MetaData> mFileMeta;  // Metadata for the whole file.
1236269d53cce5c1c9350565d3d72d92116594260cbztenghui
1246269d53cce5c1c9350565d3d72d92116594260cbztenghui    Mutex mMuxerLock;
1256269d53cce5c1c9350565d3d72d92116594260cbztenghui
1266269d53cce5c1c9350565d3d72d92116594260cbztenghui    enum State {
12711287471298193ff51ffb429686f5d63a84a621bztenghui        UNINITIALIZED,
12811287471298193ff51ffb429686f5d63a84a621bztenghui        INITIALIZED,
1296269d53cce5c1c9350565d3d72d92116594260cbztenghui        STARTED,
1306269d53cce5c1c9350565d3d72d92116594260cbztenghui        STOPPED
1316269d53cce5c1c9350565d3d72d92116594260cbztenghui    };
1326269d53cce5c1c9350565d3d72d92116594260cbztenghui    State mState;
1336269d53cce5c1c9350565d3d72d92116594260cbztenghui
1346269d53cce5c1c9350565d3d72d92116594260cbztenghui    DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer);
1356269d53cce5c1c9350565d3d72d92116594260cbztenghui};
1366269d53cce5c1c9350565d3d72d92116594260cbztenghui
1376269d53cce5c1c9350565d3d72d92116594260cbztenghui}  // namespace android
1386269d53cce5c1c9350565d3d72d92116594260cbztenghui
1396269d53cce5c1c9350565d3d72d92116594260cbztenghui#endif  // MEDIA_MUXER_H_
1406269d53cce5c1c9350565d3d72d92116594260cbztenghui
141