| /* |
| * Copyright 2018 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. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "Codec2-InputSurface" |
| #include <android-base/logging.h> |
| |
| #include <codec2/hidl/1.0/InputSurface.h> |
| #include <codec2/hidl/1.0/InputSurfaceConnection.h> |
| |
| #include <C2Component.h> |
| #include <C2Config.h> |
| |
| #include <memory> |
| |
| namespace android { |
| namespace hardware { |
| namespace media { |
| namespace c2 { |
| namespace V1_0 { |
| namespace utils { |
| |
| using namespace ::android; |
| |
| // Derived class of C2InterfaceHelper |
| class InputSurface::Interface : public C2InterfaceHelper { |
| public: |
| explicit Interface( |
| const std::shared_ptr<C2ReflectorHelper> &helper) |
| : C2InterfaceHelper(helper) { |
| |
| setDerivedInstance(this); |
| |
| addParameter( |
| DefineParam(mEos, C2_PARAMKEY_INPUT_SURFACE_EOS) |
| .withDefault(new C2InputSurfaceEosTuning(false)) |
| .withFields({C2F(mEos, value).oneOf({true, false})}) |
| .withSetter(EosSetter) |
| .build()); |
| } |
| |
| static C2R EosSetter(bool mayBlock, C2P<C2InputSurfaceEosTuning> &me) { |
| (void)mayBlock; |
| return me.F(me.v.value).validatePossible(me.v.value); |
| } |
| |
| bool eos() const { return mEos->value; } |
| |
| private: |
| std::shared_ptr<C2InputSurfaceEosTuning> mEos; |
| }; |
| |
| // Derived class of ConfigurableC2Intf |
| class InputSurface::ConfigurableIntf : public ConfigurableC2Intf { |
| public: |
| ConfigurableIntf( |
| const std::shared_ptr<InputSurface::Interface> &intf, |
| const sp<GraphicBufferSource> &source) |
| : ConfigurableC2Intf("input-surface", 0), |
| mIntf(intf), |
| mSource(source) { |
| } |
| |
| virtual ~ConfigurableIntf() override = default; |
| |
| virtual c2_status_t query( |
| const std::vector<C2Param::Index> &indices, |
| c2_blocking_t mayBlock, |
| std::vector<std::unique_ptr<C2Param>>* const params |
| ) const override { |
| return mIntf->query({}, indices, mayBlock, params); |
| } |
| |
| virtual c2_status_t config( |
| const std::vector<C2Param*> ¶ms, |
| c2_blocking_t mayBlock, |
| std::vector<std::unique_ptr<C2SettingResult>>* const failures |
| ) override { |
| c2_status_t err = mIntf->config(params, mayBlock, failures); |
| if (mIntf->eos()) { |
| sp<GraphicBufferSource> source = mSource.promote(); |
| if (source == nullptr || source->signalEndOfInputStream() != OK) { |
| // TODO: put something in |failures| |
| err = C2_BAD_VALUE; |
| } |
| // TODO: reset eos? |
| } |
| return err; |
| } |
| |
| virtual c2_status_t querySupportedParams( |
| std::vector<std::shared_ptr<C2ParamDescriptor>>* const params |
| ) const override { |
| return mIntf->querySupportedParams(params); |
| } |
| |
| virtual c2_status_t querySupportedValues( |
| std::vector<C2FieldSupportedValuesQuery>& fields, |
| c2_blocking_t mayBlock) const override { |
| return mIntf->querySupportedValues(fields, mayBlock); |
| } |
| |
| private: |
| const std::shared_ptr<InputSurface::Interface> mIntf; |
| wp<GraphicBufferSource> mSource; |
| }; |
| |
| Return<sp<InputSurface::HGraphicBufferProducer>> InputSurface::getGraphicBufferProducer() { |
| return mProducer; |
| } |
| |
| Return<sp<IConfigurable>> InputSurface::getConfigurable() { |
| return mConfigurable; |
| } |
| |
| Return<void> InputSurface::connect( |
| const sp<IInputSink>& sink, |
| connect_cb _hidl_cb) { |
| Status status; |
| sp<InputSurfaceConnection> connection; |
| if (!sink) { |
| _hidl_cb(Status::BAD_VALUE, nullptr); |
| return Void(); |
| } |
| std::shared_ptr<C2Component> comp = Component::findLocalComponent(sink); |
| if (comp) { |
| connection = new InputSurfaceConnection(mSource, comp, mStore); |
| } else { |
| connection = new InputSurfaceConnection(mSource, sink, mStore); |
| } |
| if (!connection->init()) { |
| connection = nullptr; |
| status = Status::BAD_VALUE; |
| } else { |
| status = Status::OK; |
| } |
| _hidl_cb(status, connection); |
| return Void(); |
| } |
| |
| // Constructor is exclusive to ComponentStore. |
| InputSurface::InputSurface( |
| const sp<ComponentStore>& store, |
| const std::shared_ptr<C2ReflectorHelper>& reflector, |
| const sp<HGraphicBufferProducer>& producer, |
| const sp<GraphicBufferSource>& source) |
| : mStore{store}, |
| mProducer{producer}, |
| mSource{source}, |
| mIntf{std::make_shared<Interface>(reflector)}, |
| mConfigurable{new CachedConfigurable( |
| std::make_unique<ConfigurableIntf>( |
| mIntf, source))} { |
| |
| mConfigurable->init(store.get()); |
| } |
| |
| } // namespace utils |
| } // namespace V1_0 |
| } // namespace c2 |
| } // namespace media |
| } // namespace hardware |
| } // namespace android |
| |