blob: 63c3ca55f0c7d2d5f2790df7b5f6a5c9c4d6012b [file] [log] [blame]
/*
* 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_THREE_GPP = 2,
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_