172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang/*
272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Copyright (C) 2014 The Android Open Source Project
372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *
472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Licensed under the Apache License, Version 2.0 (the "License");
572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * you may not use this file except in compliance with the License.
672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * You may obtain a copy of the License at
772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *
872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *      http://www.apache.org/licenses/LICENSE-2.0
972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *
1072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Unless required by applicable law or agreed to in writing, software
1172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * distributed under the License is distributed on an "AS IS" BASIS,
1272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * See the License for the specific language governing permissions and
1472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * limitations under the License.
1572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang */
1672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#ifndef MediaCodecSource_H_
1872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define MediaCodecSource_H_
1972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ABase.h>
2172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/AHandlerReflector.h>
226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar#include <media/stagefright/foundation/Mutexed.h>
2372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaSource.h>
24addf2cbb120346ae42e78fa739245a353db5edadChong Zhang#include <media/stagefright/PersistentSurface.h>
2516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
2672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangnamespace android {
2772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
286d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnarstruct ALooper;
2916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnarstruct AMessage;
303f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarstruct AReplyToken;
3172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangclass IGraphicBufferProducer;
3216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnarstruct MediaCodec;
3372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangclass MetaData;
3472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource : public MediaSource,
3672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                          public MediaBufferObserver {
3772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    enum FlagBits {
3872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        FLAG_USE_SURFACE_INPUT      = 1,
3916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        FLAG_PREFER_SOFTWARE_CODEC  = 4,  // used for testing only
4072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
4172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    static sp<MediaCodecSource> Create(
4372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const sp<ALooper> &looper,
4472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const sp<AMessage> &format,
4572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const sp<MediaSource> &source,
46addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            const sp<PersistentSurface> &persistentSurface = NULL,
4772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            uint32_t flags = 0);
4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool isVideo() const { return mIsVideo; }
5072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<IGraphicBufferProducer> getGraphicBufferProducer();
5161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    status_t setInputBufferTimeOffset(int64_t timeOffsetUs);
52a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    int64_t getFirstSampleSystemTimeUs();
5372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // MediaSource
5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual status_t start(MetaData *params = NULL);
5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual status_t stop();
57764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    virtual status_t pause(MetaData *params = NULL);
58ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    virtual sp<MetaData> getFormat();
5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual status_t read(
6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            MediaBuffer **buffer,
6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const ReadOptions *options = NULL);
6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // MediaBufferObserver
6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual void signalBufferReturned(MediaBuffer *buffer);
6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // for AHandlerReflector
6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void onMessageReceived(const sp<AMessage> &msg);
6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Set GraphicBufferSource stop time. GraphicBufferSource will stop
70764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // after receiving a buffer with timestamp larger or equal than stopTimeUs.
71764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // All the buffers with timestamp larger or equal to stopTimeUs will be
72764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // discarded. stopTimeUs uses SYSTEM_TIME_MONOTONIC time base.
73764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    status_t setStopStimeUs(int64_t stopTimeUs);
74764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected:
7672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual ~MediaCodecSource();
7772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate:
7972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    struct Puller;
8072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    enum {
8272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPullerNotify,
8372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatEncoderActivity,
8472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStart,
8572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStop,
8672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPause,
87d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        kWhatSetInputBufferTimeOffset,
88764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        kWhatSetStopTimeOffset,
89a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        kWhatGetFirstSampleSystemTimeUs,
906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        kWhatStopStalled,
9172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
9272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    MediaCodecSource(
9472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const sp<ALooper> &looper,
9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const sp<AMessage> &outputFormat,
9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            const sp<MediaSource> &source,
97addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            const sp<PersistentSurface> &persistentSurface,
9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            uint32_t flags = 0);
9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t onStart(MetaData *params);
101764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
102764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Pause the source at pauseStartTimeUs. For non-surface input,
103764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // buffers will be dropped immediately. For surface input, buffers
104764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // with timestamp smaller than pauseStartTimeUs will still be encoded.
105764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Buffers with timestamp larger or queal to pauseStartTimeUs will be
106764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // dropped. pauseStartTimeUs uses SYSTEM_TIME_MONOTONIC time base.
107764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    void onPause(int64_t pauseStartTimeUs);
108764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t init();
11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t initEncoder();
11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void releaseEncoder();
11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t feedEncoderInputBuffers();
113764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // Resume GraphicBufferSource at resumeStartTimeUs. Buffers
114764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // from GraphicBufferSource with timestamp larger or equal to
115764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // resumeStartTimeUs will be encoded. resumeStartTimeUs uses
116764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    // SYSTEM_TIME_MONOTONIC time base.
117764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    void resume(int64_t resumeStartTimeUs = -1ll);
11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void signalEOS(status_t err = ERROR_END_OF_STREAM);
11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool reachedEOS();
12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
12172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
12272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mLooper;
12372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mCodecLooper;
12472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AHandlerReflector<MediaCodecSource> > mReflector;
12572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mOutputFormat;
126ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    Mutexed<sp<MetaData>> mMeta;
12772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<Puller> mPuller;
12872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaCodec> mEncoder;
12972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    uint32_t mFlags;
1303f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    List<sp<AReplyToken>> mStopReplyIDQueue;
13172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mIsVideo;
13272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mStarted;
13372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mStopping;
13472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mDoMoreWorkPending;
135c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    bool mSetEncoderFormat;
136b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t mEncoderFormat;
137b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t mEncoderDataSpace;
13872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mEncoderActivityNotify;
13972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<IGraphicBufferProducer> mGraphicBufferProducer;
140addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<PersistentSurface> mPersistentSurface;
14172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    List<MediaBuffer *> mInputBufferQueue;
14272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    List<size_t> mAvailEncoderInputIndices;
14372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    List<int64_t> mDecodingTimeQueue; // decoding time (us) for video
144d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    int64_t mInputBufferTimeOffsetUs;
145a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    int64_t mFirstSampleSystemTimeUs;
146a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    bool mPausePending;
14772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
14872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    // audio drift time
14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t mFirstSampleTimeUs;
15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    List<int64_t> mDriftTimeQueue;
15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    struct Output {
1536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Output();
1546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        List<MediaBuffer*> mBufferQueue;
1556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mEncoderReachedEOS;
1566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        status_t mErrorCode;
1576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Condition mCond;
1586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    };
1596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Output> mOutput;
1606a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1616a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    int32_t mGeneration;
16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(MediaCodecSource);
16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang};
16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android
16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif /* MediaCodecSource_H_ */
169