1/*
2 * Copyright 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SIMPLE_DECODING_SOURCE_H_
18#define SIMPLE_DECODING_SOURCE_H_
19
20#include <media/MediaSource.h>
21#include <media/stagefright/foundation/AString.h>
22#include <media/stagefright/foundation/Mutexed.h>
23
24#include <utils/Condition.h>
25#include <utils/StrongPointer.h>
26
27struct ANativeWindow;
28
29namespace android {
30
31struct ALooper;
32struct AMessage;
33class MediaBuffer;
34struct MediaCodec;
35class MetaData;
36
37class SimpleDecodingSource : public MediaSource {
38public:
39    // Creates a MediaSource that uses MediaCodec to decode a compressed input |source|.
40    // The selected codec can be influenced using |flags|. This source only supports the
41    // kPreferGoogleCodec and kNonGoogleCodecsOnly |flags| - MediaCodecList.
42    // You can pass in a target |nativeWindow| to render video directly onto a surface. In this
43    // case the source will return empty buffers.
44    // This source cannot be restarted (hence the name "Simple"), all reads are blocking, and
45    // does not support secure input or pausing.
46    // if |desiredCodec| is given, use this specific codec.
47    static sp<SimpleDecodingSource> Create(
48            const sp<MediaSource> &source, uint32_t flags,
49            const sp<ANativeWindow> &nativeWindow,
50            const char *desiredCodec = NULL,
51            bool skipMediaCodecList = false);
52
53    static sp<SimpleDecodingSource> Create(
54            const sp<MediaSource> &source, uint32_t flags = 0);
55
56    virtual ~SimpleDecodingSource();
57
58    // starts this source (and it's underlying source). |params| is ignored.
59    virtual status_t start(MetaData *params = NULL);
60
61    // stops this source (and it's underlying source).
62    virtual status_t stop();
63
64    // returns the output format of this source.
65    virtual sp<MetaData> getFormat();
66
67    // reads from the source. This call always blocks.
68    virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options);
69
70    // unsupported methods
71    virtual status_t pause() { return INVALID_OPERATION; }
72
73private:
74    // Construct this using a codec, source and looper.
75    SimpleDecodingSource(
76            const sp<MediaCodec> &codec, const sp<MediaSource> &source, const sp<ALooper> &looper,
77            bool usingSurface, bool isVorbis, const sp<AMessage> &format);
78
79    sp<MediaCodec> mCodec;
80    sp<MediaSource> mSource;
81    sp<ALooper> mLooper;
82    bool mUsingSurface;
83    bool mIsVorbis;
84    enum State {
85        INIT,
86        STARTED,
87        STOPPING,
88        STOPPED,
89        ERROR,
90    };
91    AString mComponentName;
92
93    struct ProtectedState {
94        ProtectedState(const sp<AMessage> &format);
95        bool mReading;
96        Condition mReadCondition;
97
98        sp<AMessage> mFormat;
99        State mState;
100        bool mQueuedInputEOS;
101        bool mGotOutputEOS;
102    };
103    Mutexed<ProtectedState> mProtectedState;
104
105    // do the actual reading
106    status_t doRead(
107            Mutexed<ProtectedState>::Locked &me, MediaBufferBase **buffer,
108            const ReadOptions *options);
109};
110
111} // namespace android
112
113#endif
114