1 /*
2  * Copyright 2018 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "Codec2-InputSurface"
19 #include <android-base/logging.h>
20 
21 #include <codec2/hidl/1.0/InputSurface.h>
22 #include <codec2/hidl/1.0/InputSurfaceConnection.h>
23 
24 #include <C2Component.h>
25 #include <C2Config.h>
26 
27 #include <memory>
28 
29 namespace android {
30 namespace hardware {
31 namespace media {
32 namespace c2 {
33 namespace V1_0 {
34 namespace utils {
35 
36 using namespace ::android;
37 
38 // Derived class of C2InterfaceHelper
39 class InputSurface::Interface : public C2InterfaceHelper {
40 public:
Interface(const std::shared_ptr<C2ReflectorHelper> & helper)41     explicit Interface(
42             const std::shared_ptr<C2ReflectorHelper> &helper)
43         : C2InterfaceHelper(helper) {
44 
45         setDerivedInstance(this);
46 
47         addParameter(
48                 DefineParam(mEos, C2_PARAMKEY_INPUT_SURFACE_EOS)
49                 .withDefault(new C2InputSurfaceEosTuning(false))
50                 .withFields({C2F(mEos, value).oneOf({true, false})})
51                 .withSetter(EosSetter)
52                 .build());
53     }
54 
EosSetter(bool mayBlock,C2P<C2InputSurfaceEosTuning> & me)55     static C2R EosSetter(bool mayBlock, C2P<C2InputSurfaceEosTuning> &me) {
56         (void)mayBlock;
57         return me.F(me.v.value).validatePossible(me.v.value);
58     }
59 
eos() const60     bool eos() const { return mEos->value; }
61 
62 private:
63     std::shared_ptr<C2InputSurfaceEosTuning> mEos;
64 };
65 
66 // Derived class of ConfigurableC2Intf
67 class InputSurface::ConfigurableIntf : public ConfigurableC2Intf {
68 public:
ConfigurableIntf(const std::shared_ptr<InputSurface::Interface> & intf,const sp<GraphicBufferSource> & source)69     ConfigurableIntf(
70             const std::shared_ptr<InputSurface::Interface> &intf,
71             const sp<GraphicBufferSource> &source)
72         : ConfigurableC2Intf("input-surface", 0),
73           mIntf(intf),
74           mSource(source) {
75     }
76 
77     virtual ~ConfigurableIntf() override = default;
78 
query(const std::vector<C2Param::Index> & indices,c2_blocking_t mayBlock,std::vector<std::unique_ptr<C2Param>> * const params) const79     virtual c2_status_t query(
80             const std::vector<C2Param::Index> &indices,
81             c2_blocking_t mayBlock,
82             std::vector<std::unique_ptr<C2Param>>* const params
83             ) const override {
84         return mIntf->query({}, indices, mayBlock, params);
85     }
86 
config(const std::vector<C2Param * > & params,c2_blocking_t mayBlock,std::vector<std::unique_ptr<C2SettingResult>> * const failures)87     virtual c2_status_t config(
88             const std::vector<C2Param*> &params,
89             c2_blocking_t mayBlock,
90             std::vector<std::unique_ptr<C2SettingResult>>* const failures
91             ) override {
92         c2_status_t err = mIntf->config(params, mayBlock, failures);
93         if (mIntf->eos()) {
94             sp<GraphicBufferSource> source = mSource.promote();
95             if (source == nullptr || source->signalEndOfInputStream() != OK) {
96                 // TODO: put something in |failures|
97                 err = C2_BAD_VALUE;
98             }
99             // TODO: reset eos?
100         }
101         return err;
102     }
103 
querySupportedParams(std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const104     virtual c2_status_t querySupportedParams(
105             std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
106             ) const override {
107         return mIntf->querySupportedParams(params);
108     }
109 
querySupportedValues(std::vector<C2FieldSupportedValuesQuery> & fields,c2_blocking_t mayBlock) const110     virtual c2_status_t querySupportedValues(
111             std::vector<C2FieldSupportedValuesQuery>& fields,
112             c2_blocking_t mayBlock) const override {
113         return mIntf->querySupportedValues(fields, mayBlock);
114     }
115 
116 private:
117     const std::shared_ptr<InputSurface::Interface> mIntf;
118     wp<GraphicBufferSource> mSource;
119 };
120 
getGraphicBufferProducer()121 Return<sp<InputSurface::HGraphicBufferProducer>> InputSurface::getGraphicBufferProducer() {
122     return mProducer;
123 }
124 
getConfigurable()125 Return<sp<IConfigurable>> InputSurface::getConfigurable() {
126     return mConfigurable;
127 }
128 
connect(const sp<IInputSink> & sink,connect_cb _hidl_cb)129 Return<void> InputSurface::connect(
130         const sp<IInputSink>& sink,
131         connect_cb _hidl_cb) {
132     Status status;
133     sp<InputSurfaceConnection> connection;
134     if (!sink) {
135         _hidl_cb(Status::BAD_VALUE, nullptr);
136         return Void();
137     }
138     std::shared_ptr<C2Component> comp = Component::findLocalComponent(sink);
139     if (comp) {
140         connection = new InputSurfaceConnection(mSource, comp, mStore);
141     } else {
142         connection = new InputSurfaceConnection(mSource, sink, mStore);
143     }
144     if (!connection->init()) {
145         connection = nullptr;
146         status = Status::BAD_VALUE;
147     } else {
148         status = Status::OK;
149     }
150     _hidl_cb(status, connection);
151     return Void();
152 }
153 
154 // Constructor is exclusive to ComponentStore.
InputSurface(const sp<ComponentStore> & store,const std::shared_ptr<C2ReflectorHelper> & reflector,const sp<HGraphicBufferProducer> & producer,const sp<GraphicBufferSource> & source)155 InputSurface::InputSurface(
156         const sp<ComponentStore>& store,
157         const std::shared_ptr<C2ReflectorHelper>& reflector,
158         const sp<HGraphicBufferProducer>& producer,
159         const sp<GraphicBufferSource>& source)
160       : mStore{store},
161         mProducer{producer},
162         mSource{source},
163         mIntf{std::make_shared<Interface>(reflector)},
164         mConfigurable{new CachedConfigurable(
165                 std::make_unique<ConfigurableIntf>(
166                     mIntf, source))} {
167 
168     mConfigurable->init(store.get());
169 }
170 
171 }  // namespace utils
172 }  // namespace V1_0
173 }  // namespace c2
174 }  // namespace media
175 }  // namespace hardware
176 }  // namespace android
177 
178