/* * 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-Configurable" #include #include #include #include #include namespace android { namespace hardware { namespace media { namespace c2 { namespace V1_0 { namespace utils { using namespace ::android; CachedConfigurable::CachedConfigurable( std::unique_ptr&& intf) : mIntf{std::move(intf)} { } c2_status_t CachedConfigurable::init( const std::shared_ptr& cache) { // Retrieve supported parameters from store c2_status_t init = mIntf->querySupportedParams(&mSupportedParams); c2_status_t validate = cache->validate(mSupportedParams); return init == C2_OK ? C2_OK : validate; } // Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow. Return CachedConfigurable::getId() { return mIntf->getId(); } Return CachedConfigurable::getName(getName_cb _hidl_cb) { _hidl_cb(mIntf->getName()); return Void(); } Return CachedConfigurable::query( const hidl_vec& indices, bool mayBlock, query_cb _hidl_cb) { typedef C2Param::Index Index; std::vector c2heapParamIndices( (Index*)indices.data(), (Index*)indices.data() + indices.size()); std::vector> c2heapParams; c2_status_t c2res = mIntf->query( c2heapParamIndices, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK, &c2heapParams); hidl_vec params; if (!createParamsBlob(¶ms, c2heapParams)) { LOG(WARNING) << "query -- invalid output params."; } _hidl_cb(static_cast(c2res), params); return Void(); } Return CachedConfigurable::config( const hidl_vec& inParams, bool mayBlock, config_cb _hidl_cb) { // inParams is not writable, so create a copy as config modifies the parameters hidl_vec inParamsCopy = inParams; std::vector c2params; if (!parseParamsBlob(&c2params, inParamsCopy)) { LOG(WARNING) << "config -- invalid input params."; _hidl_cb(Status::CORRUPTED, hidl_vec(), hidl_vec()); return Void(); } // TODO: check if blob was invalid std::vector> c2failures; c2_status_t c2res = mIntf->config( c2params, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK, &c2failures); hidl_vec failures(c2failures.size()); { size_t ix = 0; for (const std::unique_ptr& c2result : c2failures) { if (c2result) { if (objcpy(&failures[ix], *c2result)) { ++ix; } else { LOG(DEBUG) << "config -- invalid setting results."; break; } } } failures.resize(ix); } hidl_vec outParams; if (!createParamsBlob(&outParams, c2params)) { LOG(DEBUG) << "config -- invalid output params."; } _hidl_cb((Status)c2res, failures, outParams); return Void(); } Return CachedConfigurable::querySupportedParams( uint32_t start, uint32_t count, querySupportedParams_cb _hidl_cb) { C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range( start, count); hidl_vec params(request.size()); Status res = Status::OK; size_t dstIx = 0; for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) { if (mSupportedParams[srcIx]) { if (objcpy(¶ms[dstIx], *mSupportedParams[srcIx])) { ++dstIx; } else { res = Status::CORRUPTED; LOG(WARNING) << "querySupportedParams -- invalid output params."; break; } } else { res = Status::BAD_INDEX; } } params.resize(dstIx); _hidl_cb(res, params); return Void(); } Return CachedConfigurable::querySupportedValues( const hidl_vec& inFields, bool mayBlock, querySupportedValues_cb _hidl_cb) { std::vector c2fields; { // C2FieldSupportedValuesQuery objects are restricted in that some // members are const. // C2ParamField - required for its constructor - has no constructors // from fields. Use C2ParamInspector. for (const FieldSupportedValuesQuery &query : inFields) { c2fields.emplace_back(_C2ParamInspector::CreateParamField( query.field.index, query.field.fieldId.offset, query.field.fieldId.size), query.type == FieldSupportedValuesQuery::Type::POSSIBLE ? C2FieldSupportedValuesQuery::POSSIBLE : C2FieldSupportedValuesQuery::CURRENT); } } c2_status_t c2res = mIntf->querySupportedValues( c2fields, mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK); hidl_vec outFields(inFields.size()); size_t dstIx = 0; for (const C2FieldSupportedValuesQuery &result : c2fields) { if (objcpy(&outFields[dstIx], result)) { ++dstIx; } else { outFields.resize(dstIx); c2res = C2_CORRUPTED; LOG(WARNING) << "querySupportedValues -- invalid output params."; break; } } _hidl_cb((Status)c2res, outFields); return Void(); } } // namespace utils } // namespace V1_0 } // namespace c2 } // namespace media } // namespace hardware } // namespace android