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 <system/window.h>
21
22#include <media/stagefright/MediaSource.h>
23#include <media/stagefright/foundation/AString.h>
24#include <media/stagefright/foundation/Mutexed.h>
25
26#include <utils/Condition.h>
27#include <utils/StrongPointer.h>
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<IMediaSource> &source, uint32_t flags = 0,
49            const sp<ANativeWindow> &nativeWindow = NULL,
50            const char *desiredCodec = NULL);
51
52    virtual ~SimpleDecodingSource();
53
54    // starts this source (and it's underlying source). |params| is ignored.
55    virtual status_t start(MetaData *params = NULL);
56
57    // stops this source (and it's underlying source).
58    virtual status_t stop();
59
60    // returns the output format of this source.
61    virtual sp<MetaData> getFormat();
62
63    // reads from the source. This call always blocks.
64    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options);
65
66    // unsupported methods
67    virtual status_t pause() { return INVALID_OPERATION; }
68    virtual status_t setBuffers(const Vector<MediaBuffer *> &) { return INVALID_OPERATION; }
69
70private:
71    // Construct this using a codec, source and looper.
72    SimpleDecodingSource(
73            const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
74            bool usingSurface, const sp<AMessage> &format);
75
76    sp<MediaCodec> mCodec;
77    sp<IMediaSource> mSource;
78    sp<ALooper> mLooper;
79    bool mUsingSurface;
80    enum State {
81        INIT,
82        STARTED,
83        STOPPING,
84        STOPPED,
85        ERROR,
86    };
87    AString mComponentName;
88
89    struct ProtectedState {
90        ProtectedState(const sp<AMessage> &format);
91        bool mReading;
92        Condition mReadCondition;
93
94        sp<AMessage> mFormat;
95        State mState;
96        bool mQueuedInputEOS;
97        bool mGotOutputEOS;
98    };
99    Mutexed<ProtectedState> mProtectedState;
100
101    // do the actual reading
102    status_t doRead(
103            Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options);
104};
105
106} // namespace android
107
108#endif
109