/*
 * Copyright (C) 2010 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 RTP_SOURCE_H_

#define RTP_SOURCE_H_

#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/rtsp/APacketSource.h>
#include <media/stagefright/rtsp/ARTPConnection.h>
#include <media/stagefright/rtsp/ARTPSource.h>
#include <media/stagefright/rtsp/ASessionDescription.h>
#include <media/stagefright/Utils.h>
#include <media/BufferingSettings.h>
#include <mpeg2ts/AnotherPacketSource.h>

#include <utils/KeyedVector.h>
#include <utils/Vector.h>
#include <utils/RefBase.h>

#include "NuPlayerSource.h"

namespace android {

struct ALooper;
struct AnotherPacketSource;

struct NuPlayer::RTPSource : public NuPlayer::Source {
    RTPSource(
            const sp<AMessage> &notify,
            const String8& rtpParams);

    virtual status_t getBufferingSettings(
            BufferingSettings* buffering /* nonnull */) override;
    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;

    virtual void prepareAsync();
    virtual void start();
    virtual void stop();
    virtual void pause();
    virtual void resume();

    virtual status_t feedMoreTSData();

    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);

    virtual status_t getDuration(int64_t *durationUs);
    virtual status_t seekTo(
            int64_t seekTimeUs,
            MediaPlayerSeekMode mode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC) override;

    virtual bool isRealTime() const;

    void onMessageReceived(const sp<AMessage> &msg);

    virtual void setTargetBitrate(int32_t bitrate) override;

protected:
    virtual ~RTPSource();

    virtual sp<MetaData> getFormatMeta(bool audio);

private:
    enum {
        kWhatAccessUnit = 'accU',
        kWhatAccessUnitComplete = 'accu',
        kWhatDisconnect = 'disc',
        kWhatEOS = 'eos!',
        kWhatPollBuffering = 'poll',
        kWhatSetBufferingSettings = 'sBuS',
    };

    const int64_t kBufferingPollIntervalUs = 1000000ll;

    enum State {
        DISCONNECTED,
        CONNECTING,
        CONNECTED,
        PAUSED,
    };

    struct TrackInfo {

        /* SDP of track */
        bool mIsAudio;
        int32_t mPayloadType;
        String8 mMimeType;
        String8 mCodecName;
        int32_t mCodecProfile;
        int32_t mCodecLevel;
        int32_t mWidth;
        int32_t mHeight;
        String8 mLocalIp;
        String8 mRemoteIp;
        int32_t mLocalPort;
        int32_t mRemotePort;
        int64_t mSocketNetwork;
        int32_t mTimeScale;
        int32_t mAS;

        /* RTP jitter buffer time in milliseconds */
        uint32_t mJbTimeMs;
        /* Unique ID indicates itself */
        uint32_t mSelfID;
        /* extmap:<value> for CVO will be set to here */
        int32_t mCVOExtMap;

        /* a copy of TrackInfo in RTSPSource */
        sp<AnotherPacketSource> mSource;
        uint32_t mRTPTime;
        int64_t mNormalPlaytimeUs;
        bool mNPTMappingValid;

        /* a copy of TrackInfo in MyHandler.h */
        int mRTPSocket;
        int mRTCPSocket;
        uint32_t mFirstSeqNumInSegment;
        bool mNewSegment;
        int32_t mAllowedStaleAccessUnits;
        uint32_t mRTPAnchor;
        int64_t mNTPAnchorUs;
        bool mEOSReceived;
        uint32_t mNormalPlayTimeRTP;
        int64_t mNormalPlayTimeUs;
        sp<APacketSource> mPacketSource;
        List<sp<ABuffer>> mPackets;
    };

    const String8 mRTPParams;
    uint32_t mFlags;
    State mState;
    status_t mFinalResult;

    // below 3 parameters need to be checked whether it needed or not.
    Mutex mBufferingLock;
    bool mBuffering;
    bool mInPreparationPhase;
    Mutex mBufferingSettingsLock;
    BufferingSettings mBufferingSettings;

    sp<ALooper> mLooper;

    sp<ARTPConnection> mRTPConn;

    Vector<TrackInfo> mTracks;
    sp<AnotherPacketSource> mAudioTrack;
    sp<AnotherPacketSource> mVideoTrack;

    int64_t mEOSTimeoutAudio;
    int64_t mEOSTimeoutVideo;

    /* MyHandler.h */
    bool mFirstAccessUnit;
    bool mAllTracksHaveTime;
    int64_t mNTPAnchorUs;
    int64_t mMediaAnchorUs;
    int64_t mLastMediaTimeUs;
    int64_t mNumAccessUnitsReceived;
    int32_t mLastCVOUpdated;
    bool mReceivedFirstRTCPPacket;
    bool mReceivedFirstRTPPacket;
    bool mPausing;
    int32_t mPauseGeneration;

    sp<AnotherPacketSource> getSource(bool audio);

    /* MyHandler.h */
    void onTimeUpdate(int32_t trackIndex, uint32_t rtpTime, uint64_t ntpTime);
    bool addMediaTimestamp(int32_t trackIndex, const TrackInfo *track,
            const sp<ABuffer> &accessUnit);
    bool dataReceivedOnAllChannels();
    void postQueueAccessUnit(size_t trackIndex, const sp<ABuffer> &accessUnit);
    void postQueueEOS(size_t trackIndex, status_t finalResult);
    sp<MetaData> getTrackFormat(size_t index, int32_t *timeScale);
    void onConnected();
    void onDisconnected(const sp<AMessage> &msg);

    void schedulePollBuffering();
    void onPollBuffering();

    bool haveSufficientDataOnAllTracks();

    void setEOSTimeout(bool audio, int64_t timeout);

    status_t setParameters(const String8 &params);
    status_t setParameter(const String8 &key, const String8 &value);
    void setSocketNetwork(int64_t networkHandle);
    static void TrimString(String8 *s);

    DISALLOW_EVIL_CONSTRUCTORS(RTPSource);
};

}  // namespace android

#endif  // RTP_SOURCE_H_
