/*
 * 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 <map>
#include <mutex>
#include <vector>

#include "media/stagefright/foundation/ABase.h"
#include "MediaMuxerBase.h"

namespace android {

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

// 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 MediaMuxerBase {
public:
    /**
     * Creates the muxer for a given output format.
     * @param fd : file descriptor of the output file.
     * @param format : output format of the muxer. e.g.: webm/mp4/ogg
     * @return writer's object or nullptr if error.
     */
    static MediaMuxer* create(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) ;

    /**
     * Gets the number of tracks added successfully.  Should be called in
     * INITIALIZED(after constructor) or STARTED(after start()) state.
     * @return the number of tracks or -1 in wrong state.
     */
    ssize_t getTrackCount();

    /**
     * Gets the format of the track by their index.
     * @param idx : index of the track whose format is wanted.
     * @return smart pointer to AMessage containing the format details.
     */
    sp<AMessage> getTrackFormat(size_t idx);

private:
    // Construct the muxer with the file descriptor. Note that the MediaMuxer
    // will close this file at stop().
    // This constructor is made private to ensure that MediaMuxer::create() is used instead.
    MediaMuxer(int fd, OutputFormat format);

    const OutputFormat mFormat;
    sp<MediaWriter> mWriter;
    Vector< sp<MediaAdapter> > mTrackList;  // Each track has its MediaAdapter.
    Vector< sp<AMessage> > mFormatList; // Format of each track.
    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_

