summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/codecs/aac/Android.bp30
-rw-r--r--media/codecs/aac/C2SoftAacDec.cpp941
-rw-r--r--media/codecs/aac/C2SoftAacDec.h109
-rw-r--r--media/codecs/aac/C2SoftAacEnc.cpp603
-rw-r--r--media/codecs/aac/C2SoftAacEnc.h75
-rw-r--r--media/codecs/aac/DrcPresModeWrap.cpp372
-rw-r--r--media/codecs/aac/DrcPresModeWrap.h62
-rw-r--r--media/codecs/aac/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/aac/NOTICE190
-rw-r--r--media/codecs/aac/patent_disclaimer.txt9
-rw-r--r--media/codecs/amr_nb_wb/Android.bp77
-rw-r--r--media/codecs/amr_nb_wb/C2SoftAmrDec.cpp438
-rw-r--r--media/codecs/amr_nb_wb/C2SoftAmrDec.h68
-rw-r--r--media/codecs/amr_nb_wb/C2SoftAmrNbEnc.cpp355
-rw-r--r--media/codecs/amr_nb_wb/C2SoftAmrNbEnc.h67
-rw-r--r--media/codecs/amr_nb_wb/C2SoftAmrWbEnc.cpp430
-rw-r--r--media/codecs/amr_nb_wb/C2SoftAmrWbEnc.h71
-rw-r--r--media/codecs/amr_nb_wb/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/amr_nb_wb/NOTICE190
-rw-r--r--media/codecs/amr_nb_wb/patent_disclaimer.txt9
-rw-r--r--media/codecs/avc/Android.bp37
-rw-r--r--media/codecs/avc/C2SoftAvcDec.cpp978
-rw-r--r--media/codecs/avc/C2SoftAvcDec.h196
-rw-r--r--media/codecs/avc/C2SoftAvcEnc.cpp1559
-rw-r--r--media/codecs/avc/C2SoftAvcEnc.h296
-rw-r--r--media/codecs/base/Android.bp129
-rw-r--r--media/codecs/base/SimpleC2Component.cpp569
-rw-r--r--media/codecs/base/SimpleC2Interface.cpp315
-rw-r--r--media/codecs/base/include/SimpleC2Component.h244
-rw-r--r--media/codecs/base/include/SimpleC2Interface.h236
-rw-r--r--media/codecs/cmds/Android.bp37
-rw-r--r--media/codecs/cmds/codec2.cpp482
-rw-r--r--media/codecs/flac/Android.bp27
-rw-r--r--media/codecs/flac/C2SoftFlacDec.cpp372
-rw-r--r--media/codecs/flac/C2SoftFlacDec.h66
-rw-r--r--media/codecs/flac/C2SoftFlacEnc.cpp460
-rw-r--r--media/codecs/flac/C2SoftFlacEnc.h89
-rw-r--r--media/codecs/flac/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/flac/NOTICE190
-rw-r--r--media/codecs/g711/Android.bp23
-rw-r--r--media/codecs/g711/C2SoftG711Dec.cpp323
-rw-r--r--media/codecs/g711/C2SoftG711Dec.h59
-rw-r--r--media/codecs/g711/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/g711/NOTICE190
-rw-r--r--media/codecs/gsm/Android.bp11
-rw-r--r--media/codecs/gsm/C2SoftGsmDec.cpp311
-rw-r--r--media/codecs/gsm/C2SoftGsmDec.h65
-rw-r--r--media/codecs/gsm/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/gsm/NOTICE190
-rw-r--r--media/codecs/hevc/Android.bp16
-rw-r--r--media/codecs/hevc/C2SoftHevcDec.cpp976
-rw-r--r--media/codecs/hevc/C2SoftHevcDec.h152
-rw-r--r--media/codecs/mp3/Android.bp11
-rw-r--r--media/codecs/mp3/C2SoftMp3Dec.cpp558
-rw-r--r--media/codecs/mp3/C2SoftMp3Dec.h76
-rw-r--r--media/codecs/mp3/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/mp3/NOTICE190
-rw-r--r--media/codecs/mp3/patent_disclaimer.txt9
-rw-r--r--media/codecs/mpeg2/Android.bp16
-rw-r--r--media/codecs/mpeg2/C2SoftMpeg2Dec.cpp1069
-rw-r--r--media/codecs/mpeg2/C2SoftMpeg2Dec.h195
-rw-r--r--media/codecs/mpeg4_h263/Android.bp66
-rw-r--r--media/codecs/mpeg4_h263/C2SoftMpeg4Dec.cpp746
-rw-r--r--media/codecs/mpeg4_h263/C2SoftMpeg4Dec.h77
-rw-r--r--media/codecs/mpeg4_h263/C2SoftMpeg4Enc.cpp671
-rw-r--r--media/codecs/mpeg4_h263/C2SoftMpeg4Enc.h83
-rw-r--r--media/codecs/mpeg4_h263/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/mpeg4_h263/NOTICE190
-rw-r--r--media/codecs/mpeg4_h263/patent_disclaimer.txt9
-rw-r--r--media/codecs/opus/Android.bp11
-rw-r--r--media/codecs/opus/C2SoftOpusDec.cpp544
-rw-r--r--media/codecs/opus/C2SoftOpusDec.h79
-rw-r--r--media/codecs/raw/Android.bp9
-rw-r--r--media/codecs/raw/C2SoftRawDec.cpp233
-rw-r--r--media/codecs/raw/C2SoftRawDec.h53
-rw-r--r--media/codecs/raw/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/raw/NOTICE190
-rw-r--r--media/codecs/vorbis/Android.bp11
-rw-r--r--media/codecs/vorbis/C2SoftVorbisDec.cpp493
-rw-r--r--media/codecs/vorbis/C2SoftVorbisDec.h70
-rw-r--r--media/codecs/vorbis/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/vorbis/NOTICE190
-rw-r--r--media/codecs/vpx/Android.bp60
-rw-r--r--media/codecs/vpx/C2SoftVp8Enc.cpp114
-rw-r--r--media/codecs/vpx/C2SoftVp8Enc.h60
-rw-r--r--media/codecs/vpx/C2SoftVp9Enc.cpp144
-rw-r--r--media/codecs/vpx/C2SoftVp9Enc.h59
-rw-r--r--media/codecs/vpx/C2SoftVpxDec.cpp697
-rw-r--r--media/codecs/vpx/C2SoftVpxDec.h79
-rw-r--r--media/codecs/vpx/C2SoftVpxEnc.cpp670
-rw-r--r--media/codecs/vpx/C2SoftVpxEnc.h437
-rw-r--r--media/codecs/vpx/MODULE_LICENSE_APACHE20
-rw-r--r--media/codecs/vpx/NOTICE190
-rw-r--r--media/codecs/xaac/Android.bp11
-rw-r--r--media/codecs/xaac/C2SoftXaacDec.cpp1583
-rw-r--r--media/codecs/xaac/C2SoftXaacDec.h131
-rw-r--r--media/sfplugin/Android.bp60
-rw-r--r--media/sfplugin/C2OMXNode.cpp329
-rw-r--r--media/sfplugin/C2OMXNode.h103
-rw-r--r--media/sfplugin/CCodec.cpp1768
-rw-r--r--media/sfplugin/CCodec.h185
-rw-r--r--media/sfplugin/CCodecBufferChannel.cpp2862
-rw-r--r--media/sfplugin/CCodecBufferChannel.h416
-rw-r--r--media/sfplugin/CCodecConfig.cpp1610
-rw-r--r--media/sfplugin/CCodecConfig.h345
-rw-r--r--media/sfplugin/Codec2Buffer.cpp812
-rw-r--r--media/sfplugin/Codec2Buffer.h403
-rw-r--r--media/sfplugin/Codec2InfoBuilder.cpp653
-rw-r--r--media/sfplugin/Codec2InfoBuilder.h34
-rw-r--r--media/sfplugin/InputSurfaceWrapper.h107
-rw-r--r--media/sfplugin/ReflectedParamUpdater.cpp575
-rw-r--r--media/sfplugin/ReflectedParamUpdater.h214
-rw-r--r--media/sfplugin/SkipCutBuffer.cpp206
-rw-r--r--media/sfplugin/SkipCutBuffer.h67
-rw-r--r--media/sfplugin/tests/Android.bp56
-rw-r--r--media/sfplugin/tests/MediaCodec_sanity_test.cpp453
-rw-r--r--media/sfplugin/tests/ReflectedParamUpdater_test.cpp352
-rw-r--r--media/sfplugin/utils/Android.bp40
-rw-r--r--media/sfplugin/utils/Codec2BufferUtils.cpp533
-rw-r--r--media/sfplugin/utils/Codec2BufferUtils.h166
-rw-r--r--media/sfplugin/utils/Codec2Mapper.cpp815
-rw-r--r--media/sfplugin/utils/Codec2Mapper.h78
122 files changed, 0 insertions, 36020 deletions
diff --git a/media/codecs/aac/Android.bp b/media/codecs/aac/Android.bp
deleted file mode 100644
index b70f30a..0000000
--- a/media/codecs/aac/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2aacdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: [
- "C2SoftAacDec.cpp",
- "DrcPresModeWrap.cpp",
- ],
-
- static_libs: [
- "libFraunhoferAAC",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2aacenc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftAacEnc.cpp"],
-
- static_libs: [
- "libFraunhoferAAC",
- ],
-}
diff --git a/media/codecs/aac/C2SoftAacDec.cpp b/media/codecs/aac/C2SoftAacDec.cpp
deleted file mode 100644
index c7c8442..0000000
--- a/media/codecs/aac/C2SoftAacDec.cpp
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (C) 2017 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 "C2SoftAacDec"
-#include <log/log.h>
-
-#include <inttypes.h>
-#include <math.h>
-#include <numeric>
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/misc.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftAacDec.h"
-
-#define FILEREAD_MAX_LAYERS 2
-
-#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
-#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
-#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
-// names of properties that can be used to override the default DRC settings
-#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
-#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
-#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
-#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
-#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
-#define PROP_DRC_OVERRIDE_EFFECT "ro.aac_drc_effect_type"
-
-namespace android {
-
-class C2SoftAacDec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_AAC))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).oneOf({
- 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
- })})
- .withSetter(Setter<decltype(*mSampleRate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 8)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
-
- addParameter(
- DefineParam(mAacFormat, C2_NAME_STREAM_AAC_FORMAT_SETTING)
- .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
- .withFields({C2F(mAacFormat, value).oneOf({
- C2AacStreamFormatRaw, C2AacStreamFormatAdts
- })})
- .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_AAC_LC,
- C2Config::PROFILE_AAC_HE,
- C2Config::PROFILE_AAC_HE_PS,
- C2Config::PROFILE_AAC_LD,
- C2Config::PROFILE_AAC_ELD,
- C2Config::PROFILE_AAC_ER_SCALABLE,
- C2Config::PROFILE_AAC_XHE}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_UNUSED
- })
- })
- .withSetter(ProfileLevelSetter)
- .build());
-
- addParameter(
- DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
- .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
- .withFields({
- C2F(mDrcCompressMode, value).oneOf({
- C2Config::DRC_COMPRESSION_ODM_DEFAULT,
- C2Config::DRC_COMPRESSION_NONE,
- C2Config::DRC_COMPRESSION_LIGHT,
- C2Config::DRC_COMPRESSION_HEAVY})
- })
- .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
- .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
- .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
- .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
- .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
- .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
- .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
- .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
- .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
- .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
- .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
- .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
- .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
- .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
- .withFields({
- C2F(mDrcEffectType, value).oneOf({
- C2Config::DRC_EFFECT_ODM_DEFAULT,
- C2Config::DRC_EFFECT_OFF,
- C2Config::DRC_EFFECT_NONE,
- C2Config::DRC_EFFECT_LATE_NIGHT,
- C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
- C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
- C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
- C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
- C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
- })
- .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
- .build());
- }
-
- bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
- (void)mayBlock;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
- int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
- int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
- int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
- int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
- int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
- int32_t getDrcEffectType() const { return mDrcEffectType->value; }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
- std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
- std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
- std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
- std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
- std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
- std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
- // TODO Add : C2StreamAacSbrModeTuning
-};
-
-constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
-
-C2SoftAacDec::C2SoftAacDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mAACDecoder(nullptr),
- mStreamInfo(nullptr),
- mSignalledError(false),
- mOutputDelayRingBuffer(nullptr) {
-}
-
-C2SoftAacDec::~C2SoftAacDec() {
- onRelease();
-}
-
-c2_status_t C2SoftAacDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftAacDec::onStop() {
- drainDecoder();
- // reset the "configured" state
- mOutputDelayCompensated = 0;
- mOutputDelayRingBufferWritePos = 0;
- mOutputDelayRingBufferReadPos = 0;
- mOutputDelayRingBufferFilled = 0;
- mBuffersInfo.clear();
-
- // To make the codec behave the same before and after a reset, we need to invalidate the
- // streaminfo struct. This does that:
- mStreamInfo->sampleRate = 0; // TODO: mStreamInfo is read only
-
- mSignalledError = false;
-
- return C2_OK;
-}
-
-void C2SoftAacDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftAacDec::onRelease() {
- if (mAACDecoder) {
- aacDecoder_Close(mAACDecoder);
- mAACDecoder = nullptr;
- }
- if (mOutputDelayRingBuffer) {
- delete[] mOutputDelayRingBuffer;
- mOutputDelayRingBuffer = nullptr;
- }
-}
-
-status_t C2SoftAacDec::initDecoder() {
- ALOGV("initDecoder()");
- status_t status = UNKNOWN_ERROR;
- mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
- if (mAACDecoder != nullptr) {
- mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
- if (mStreamInfo != nullptr) {
- status = OK;
- }
- }
-
- mOutputDelayCompensated = 0;
- mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
- mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
- mOutputDelayRingBufferWritePos = 0;
- mOutputDelayRingBufferReadPos = 0;
- mOutputDelayRingBufferFilled = 0;
-
- if (mAACDecoder == nullptr) {
- ALOGE("AAC decoder is null. TODO: Can not call aacDecoder_SetParam in the following code");
- }
-
- //aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE, 0);
-
- //init DRC wrapper
- mDrcWrap.setDecoderHandle(mAACDecoder);
- mDrcWrap.submitStreamData(mStreamInfo);
-
- // for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
- // TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
-
- // DRC_PRES_MODE_WRAP_DESIRED_TARGET
- int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
- ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
-
- // DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
-
- int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
- ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
-
- // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
- int32_t boostFactor = mIntf->getDrcBoostFactor();
- ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
-
- // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
- int32_t compressMode = mIntf->getDrcCompressMode();
- ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
-
- // DRC_PRES_MODE_WRAP_ENCODER_TARGET
- int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
- ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
-
- // AAC_UNIDRC_SET_EFFECT
- int32_t effectType = mIntf->getDrcEffectType();
- ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
- aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
-
- // By default, the decoder creates a 5.1 channel downmix signal.
- // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
- aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
-
- return status;
-}
-
-bool C2SoftAacDec::outputDelayRingBufferPutSamples(INT_PCM *samples, int32_t numSamples) {
- if (numSamples == 0) {
- return true;
- }
- if (outputDelayRingBufferSpaceLeft() < numSamples) {
- ALOGE("RING BUFFER WOULD OVERFLOW");
- return false;
- }
- if (mOutputDelayRingBufferWritePos + numSamples <= mOutputDelayRingBufferSize
- && (mOutputDelayRingBufferReadPos <= mOutputDelayRingBufferWritePos
- || mOutputDelayRingBufferReadPos > mOutputDelayRingBufferWritePos + numSamples)) {
- // faster memcopy loop without checks, if the preconditions allow this
- for (int32_t i = 0; i < numSamples; i++) {
- mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos++] = samples[i];
- }
-
- if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
- mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
- }
- } else {
- ALOGV("slow C2SoftAacDec::outputDelayRingBufferPutSamples()");
-
- for (int32_t i = 0; i < numSamples; i++) {
- mOutputDelayRingBuffer[mOutputDelayRingBufferWritePos] = samples[i];
- mOutputDelayRingBufferWritePos++;
- if (mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferSize) {
- mOutputDelayRingBufferWritePos -= mOutputDelayRingBufferSize;
- }
- }
- }
- mOutputDelayRingBufferFilled += numSamples;
- return true;
-}
-
-int32_t C2SoftAacDec::outputDelayRingBufferGetSamples(INT_PCM *samples, int32_t numSamples) {
-
- if (numSamples > mOutputDelayRingBufferFilled) {
- ALOGE("RING BUFFER WOULD UNDERRUN");
- return -1;
- }
-
- if (mOutputDelayRingBufferReadPos + numSamples <= mOutputDelayRingBufferSize
- && (mOutputDelayRingBufferWritePos < mOutputDelayRingBufferReadPos
- || mOutputDelayRingBufferWritePos >= mOutputDelayRingBufferReadPos + numSamples)) {
- // faster memcopy loop without checks, if the preconditions allow this
- if (samples != nullptr) {
- for (int32_t i = 0; i < numSamples; i++) {
- samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos++];
- }
- } else {
- mOutputDelayRingBufferReadPos += numSamples;
- }
- if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
- mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
- }
- } else {
- ALOGV("slow C2SoftAacDec::outputDelayRingBufferGetSamples()");
-
- for (int32_t i = 0; i < numSamples; i++) {
- if (samples != nullptr) {
- samples[i] = mOutputDelayRingBuffer[mOutputDelayRingBufferReadPos];
- }
- mOutputDelayRingBufferReadPos++;
- if (mOutputDelayRingBufferReadPos >= mOutputDelayRingBufferSize) {
- mOutputDelayRingBufferReadPos -= mOutputDelayRingBufferSize;
- }
- }
- }
- mOutputDelayRingBufferFilled -= numSamples;
- return numSamples;
-}
-
-int32_t C2SoftAacDec::outputDelayRingBufferSamplesAvailable() {
- return mOutputDelayRingBufferFilled;
-}
-
-int32_t C2SoftAacDec::outputDelayRingBufferSpaceLeft() {
- return mOutputDelayRingBufferSize - outputDelayRingBufferSamplesAvailable();
-}
-
-void C2SoftAacDec::drainRingBuffer(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool,
- bool eos) {
- while (!mBuffersInfo.empty() && outputDelayRingBufferSamplesAvailable()
- >= mStreamInfo->frameSize * mStreamInfo->numChannels) {
- Info &outInfo = mBuffersInfo.front();
- ALOGV("outInfo.frameIndex = %" PRIu64, outInfo.frameIndex);
- int samplesize __unused = mStreamInfo->numChannels * sizeof(int16_t);
-
- int available = outputDelayRingBufferSamplesAvailable();
- int numFrames = outInfo.decodedSizes.size();
- int numSamples = numFrames * (mStreamInfo->frameSize * mStreamInfo->numChannels);
- if (available < numSamples) {
- if (eos) {
- numSamples = available;
- } else {
- break;
- }
- }
- ALOGV("%d samples available (%d), or %d frames",
- numSamples, available, numFrames);
- ALOGV("getting %d from ringbuffer", numSamples);
-
- std::shared_ptr<C2LinearBlock> block;
- std::function<void(const std::unique_ptr<C2Work>&)> fillWork =
- [&block, numSamples, pool, this]()
- -> std::function<void(const std::unique_ptr<C2Work>&)> {
- auto fillEmptyWork = [](
- const std::unique_ptr<C2Work> &work, c2_status_t err) {
- work->result = err;
- C2FrameData &output = work->worklets.front()->output;
- output.flags = work->input.flags;
- output.buffers.clear();
- output.ordinal = work->input.ordinal;
-
- work->workletsProcessed = 1u;
- };
-
- using namespace std::placeholders;
- if (numSamples == 0) {
- return std::bind(fillEmptyWork, _1, C2_OK);
- }
-
- // TODO: error handling, proper usage, etc.
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(
- numSamples * sizeof(int16_t), usage, &block);
- if (err != C2_OK) {
- ALOGD("failed to fetch a linear block (%d)", err);
- return std::bind(fillEmptyWork, _1, C2_NO_MEMORY);
- }
- C2WriteView wView = block->map().get();
- // TODO
- INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(wView.data());
- int32_t ns = outputDelayRingBufferGetSamples(outBuffer, numSamples);
- if (ns != numSamples) {
- ALOGE("not a complete frame of samples available");
- mSignalledError = true;
- return std::bind(fillEmptyWork, _1, C2_CORRUPTED);
- }
- return [buffer = createLinearBuffer(block)](
- const std::unique_ptr<C2Work> &work) {
- work->result = C2_OK;
- C2FrameData &output = work->worklets.front()->output;
- output.flags = work->input.flags;
- output.buffers.clear();
- output.buffers.push_back(buffer);
- output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- }();
-
- if (work && work->input.ordinal.frameIndex == c2_cntr64_t(outInfo.frameIndex)) {
- fillWork(work);
- } else {
- finish(outInfo.frameIndex, fillWork);
- }
-
- ALOGV("out timestamp %" PRIu64 " / %u", outInfo.timestamp, block ? block->capacity() : 0);
- mBuffersInfo.pop_front();
- }
-}
-
-void C2SoftAacDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError) {
- return;
- }
-
- UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
- UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
- UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
-
- INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
- C2ReadView view = mDummyReadView;
- size_t offset = 0u;
- size_t size = 0u;
- if (!work->input.buffers.empty()) {
- view = work->input.buffers[0]->data().linearBlocks().front().map().get();
- size = view.capacity();
- }
-
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
- bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
-
- //TODO
-#if 0
- if (mInputBufferCount == 0 && !codecConfig) {
- ALOGW("first buffer should have FLAG_CODEC_CONFIG set");
- codecConfig = true;
- }
-#endif
- if (codecConfig && size > 0u) {
- // const_cast because of libAACdec method signature.
- inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
- inBufferLength[0] = size;
-
- AAC_DECODER_ERROR decoderErr =
- aacDecoder_ConfigRaw(mAACDecoder,
- inBuffer,
- inBufferLength);
-
- if (decoderErr != AAC_DEC_OK) {
- ALOGE("aacDecoder_ConfigRaw decoderErr = 0x%4.4x", decoderErr);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->worklets.front()->output.buffers.clear();
- return;
- }
-
- Info inInfo;
- inInfo.frameIndex = work->input.ordinal.frameIndex.peeku();
- inInfo.timestamp = work->input.ordinal.timestamp.peeku();
- inInfo.bufferSize = size;
- inInfo.decodedSizes.clear();
- while (size > 0u) {
- ALOGV("size = %zu", size);
- if (mIntf->isAdts()) {
- size_t adtsHeaderSize = 0;
- // skip 30 bits, aac_frame_length follows.
- // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
-
- const uint8_t *adtsHeader = view.data() + offset;
-
- bool signalError = false;
- if (size < 7) {
- ALOGE("Audio data too short to contain even the ADTS header. "
- "Got %zu bytes.", size);
- hexdump(adtsHeader, size);
- signalError = true;
- } else {
- bool protectionAbsent = (adtsHeader[1] & 1);
-
- unsigned aac_frame_length =
- ((adtsHeader[3] & 3) << 11)
- | (adtsHeader[4] << 3)
- | (adtsHeader[5] >> 5);
-
- if (size < aac_frame_length) {
- ALOGE("Not enough audio data for the complete frame. "
- "Got %zu bytes, frame size according to the ADTS "
- "header is %u bytes.",
- size, aac_frame_length);
- hexdump(adtsHeader, size);
- signalError = true;
- } else {
- adtsHeaderSize = (protectionAbsent ? 7 : 9);
- if (aac_frame_length < adtsHeaderSize) {
- signalError = true;
- } else {
- // const_cast because of libAACdec method signature.
- inBuffer[0] = const_cast<UCHAR *>(adtsHeader + adtsHeaderSize);
- inBufferLength[0] = aac_frame_length - adtsHeaderSize;
-
- offset += adtsHeaderSize;
- size -= adtsHeaderSize;
- }
- }
- }
-
- if (signalError) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- } else {
- // const_cast because of libAACdec method signature.
- inBuffer[0] = const_cast<UCHAR *>(view.data() + offset);
- inBufferLength[0] = size;
- }
-
- // Fill and decode
- bytesValid[0] = inBufferLength[0];
-
- INT prevSampleRate = mStreamInfo->sampleRate;
- INT prevNumChannels = mStreamInfo->numChannels;
-
- aacDecoder_Fill(mAACDecoder,
- inBuffer,
- inBufferLength,
- bytesValid);
-
- // run DRC check
- mDrcWrap.submitStreamData(mStreamInfo);
- mDrcWrap.update();
-
- UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
- size -= inBufferUsedLength;
- offset += inBufferUsedLength;
-
- AAC_DECODER_ERROR decoderErr;
- do {
- if (outputDelayRingBufferSpaceLeft() <
- (mStreamInfo->frameSize * mStreamInfo->numChannels)) {
- ALOGV("skipping decode: not enough space left in ringbuffer");
- // discard buffer
- size = 0;
- break;
- }
-
- int numConsumed = mStreamInfo->numTotalBytes;
- decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
- tmpOutBuffer,
- 2048 * MAX_CHANNEL_COUNT,
- 0 /* flags */);
-
- numConsumed = mStreamInfo->numTotalBytes - numConsumed;
-
- if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
- break;
- }
- inInfo.decodedSizes.push_back(numConsumed);
-
- if (decoderErr != AAC_DEC_OK) {
- ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
- }
-
- if (bytesValid[0] != 0) {
- ALOGE("bytesValid[0] != 0 should never happen");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- size_t numOutBytes =
- mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
-
- if (decoderErr == AAC_DEC_OK) {
- if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
- mStreamInfo->frameSize * mStreamInfo->numChannels)) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- } else {
- ALOGW("AAC decoder returned error 0x%4.4x, substituting silence", decoderErr);
-
- memset(tmpOutBuffer, 0, numOutBytes); // TODO: check for overflow
-
- if (!outputDelayRingBufferPutSamples(tmpOutBuffer,
- mStreamInfo->frameSize * mStreamInfo->numChannels)) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- // Discard input buffer.
- size = 0;
-
- aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
-
- // After an error, replace bufferSize with the sum of the
- // decodedSizes to resynchronize the in/out lists.
- inInfo.decodedSizes.pop_back();
- inInfo.bufferSize = std::accumulate(
- inInfo.decodedSizes.begin(), inInfo.decodedSizes.end(), 0);
-
- // fall through
- }
-
- /*
- * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
- * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
- * rate system and the sampling rate in the final output is actually
- * doubled compared with the core AAC decoder sampling rate.
- *
- * Explicit signalling is done by explicitly defining SBR audio object
- * type in the bitstream. Implicit signalling is done by embedding
- * SBR content in AAC extension payload specific to SBR, and hence
- * requires an AAC decoder to perform pre-checks on actual audio frames.
- *
- * Thus, we could not say for sure whether a stream is
- * AAC+/eAAC+ until the first data frame is decoded.
- */
- if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
- // if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
- ALOGD("Invalid AAC stream");
- // TODO: notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
- // mSignalledError = true;
- // }
- } else if ((mStreamInfo->sampleRate != prevSampleRate) ||
- (mStreamInfo->numChannels != prevNumChannels)) {
- ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
- prevSampleRate, mStreamInfo->sampleRate,
- prevNumChannels, mStreamInfo->numChannels);
-
- C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate);
- C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config(
- { &sampleRateInfo, &channelCountInfo },
- C2_MAY_BLOCK,
- &failures);
- if (err == OK) {
- // TODO: this does not handle the case where the values are
- // altered during config.
- C2FrameData &output = work->worklets.front()->output;
- output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
- output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
- } else {
- ALOGE("Config Update failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- ALOGV("size = %zu", size);
- } while (decoderErr == AAC_DEC_OK);
- }
-
- int32_t outputDelay = mStreamInfo->outputDelay * mStreamInfo->numChannels;
-
- mBuffersInfo.push_back(std::move(inInfo));
- work->workletsProcessed = 0u;
- if (!eos && mOutputDelayCompensated < outputDelay) {
- // discard outputDelay at the beginning
- int32_t toCompensate = outputDelay - mOutputDelayCompensated;
- int32_t discard = outputDelayRingBufferSamplesAvailable();
- if (discard > toCompensate) {
- discard = toCompensate;
- }
- int32_t discarded = outputDelayRingBufferGetSamples(nullptr, discard);
- mOutputDelayCompensated += discarded;
- return;
- }
-
- if (eos) {
- drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
- } else {
- drainRingBuffer(work, pool, false /* not EOS */);
- }
-}
-
-c2_status_t C2SoftAacDec::drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work) {
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- bool eos = (drainMode == DRAIN_COMPONENT_WITH_EOS);
-
- drainDecoder();
- drainRingBuffer(work, pool, eos);
-
- if (eos) {
- auto fillEmptyWork = [](const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- while (mBuffersInfo.size() > 1u) {
- finish(mBuffersInfo.front().frameIndex, fillEmptyWork);
- mBuffersInfo.pop_front();
- }
- if (work && work->workletsProcessed == 0u) {
- fillEmptyWork(work);
- }
- mBuffersInfo.clear();
- }
-
- return C2_OK;
-}
-
-c2_status_t C2SoftAacDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- return drainInternal(drainMode, pool, nullptr);
-}
-
-c2_status_t C2SoftAacDec::onFlush_sm() {
- drainDecoder();
- mBuffersInfo.clear();
-
- int avail;
- while ((avail = outputDelayRingBufferSamplesAvailable()) > 0) {
- if (avail > mStreamInfo->frameSize * mStreamInfo->numChannels) {
- avail = mStreamInfo->frameSize * mStreamInfo->numChannels;
- }
- int32_t ns = outputDelayRingBufferGetSamples(nullptr, avail);
- if (ns != avail) {
- ALOGW("not a complete frame of samples available");
- break;
- }
- }
- mOutputDelayRingBufferReadPos = mOutputDelayRingBufferWritePos;
-
- return C2_OK;
-}
-
-void C2SoftAacDec::drainDecoder() {
- // flush decoder until outputDelay is compensated
- while (mOutputDelayCompensated > 0) {
- // a buffer big enough for MAX_CHANNEL_COUNT channels of decoded HE-AAC
- INT_PCM tmpOutBuffer[2048 * MAX_CHANNEL_COUNT];
-
- // run DRC check
- mDrcWrap.submitStreamData(mStreamInfo);
- mDrcWrap.update();
-
- AAC_DECODER_ERROR decoderErr =
- aacDecoder_DecodeFrame(mAACDecoder,
- tmpOutBuffer,
- 2048 * MAX_CHANNEL_COUNT,
- AACDEC_FLUSH);
- if (decoderErr != AAC_DEC_OK) {
- ALOGW("aacDecoder_DecodeFrame decoderErr = 0x%4.4x", decoderErr);
- }
-
- int32_t tmpOutBufferSamples = mStreamInfo->frameSize * mStreamInfo->numChannels;
- if (tmpOutBufferSamples > mOutputDelayCompensated) {
- tmpOutBufferSamples = mOutputDelayCompensated;
- }
- outputDelayRingBufferPutSamples(tmpOutBuffer, tmpOutBufferSamples);
-
- mOutputDelayCompensated -= tmpOutBufferSamples;
- }
-}
-
-class C2SoftAacDecFactory : public C2ComponentFactory {
-public:
- C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAacDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAacDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftAacDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAacDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAacDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/aac/C2SoftAacDec.h b/media/codecs/aac/C2SoftAacDec.h
deleted file mode 100644
index 965c29e..0000000
--- a/media/codecs/aac/C2SoftAacDec.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AAC_DEC_H_
-#define ANDROID_C2_SOFT_AAC_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-#include "aacdecoder_lib.h"
-#include "DrcPresModeWrap.h"
-
-namespace android {
-
-struct C2SoftAacDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftAacDec(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftAacDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- enum {
- kNumDelayBlocksMax = 8,
- };
-
- std::shared_ptr<IntfImpl> mIntf;
-
- HANDLE_AACDECODER mAACDecoder;
- CStreamInfo *mStreamInfo;
- bool mIsFirst;
- size_t mInputBufferCount;
- size_t mOutputBufferCount;
- bool mSignalledError;
- struct Info {
- uint64_t frameIndex;
- size_t bufferSize;
- uint64_t timestamp;
- std::vector<int32_t> decodedSizes;
- };
- std::list<Info> mBuffersInfo;
-
- CDrcPresModeWrapper mDrcWrap;
-
- enum {
- NONE,
- AWAITING_DISABLED,
- AWAITING_ENABLED
- } mOutputPortSettingsChange;
-
- void initPorts();
- status_t initDecoder();
- bool isConfigured() const;
- void drainDecoder();
-
- void drainRingBuffer(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool,
- bool eos);
- c2_status_t drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work);
-
-// delay compensation
- bool mEndOfInput;
- bool mEndOfOutput;
- int32_t mOutputDelayCompensated;
- int32_t mOutputDelayRingBufferSize;
- short *mOutputDelayRingBuffer;
- int32_t mOutputDelayRingBufferWritePos;
- int32_t mOutputDelayRingBufferReadPos;
- int32_t mOutputDelayRingBufferFilled;
- bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
- int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
- int32_t outputDelayRingBufferSamplesAvailable();
- int32_t outputDelayRingBufferSpaceLeft();
-
- C2_DO_NOT_COPY(C2SoftAacDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AAC_DEC_H_
diff --git a/media/codecs/aac/C2SoftAacEnc.cpp b/media/codecs/aac/C2SoftAacEnc.cpp
deleted file mode 100644
index 87730ae..0000000
--- a/media/codecs/aac/C2SoftAacEnc.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2012 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 "C2SoftAacEnc"
-#include <utils/Log.h>
-
-#include <inttypes.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include "C2SoftAacEnc.h"
-
-namespace android {
-
-class C2SoftAacEnc::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_AAC))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::input(0u, 44100))
- .withFields({C2F(mSampleRate, value).oneOf({
- 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
- })})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 6)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .calculatedAs(MaxBufSizeCalculator, mChannelCount)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::output(0u,
- C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_AAC_LC,
- C2Config::PROFILE_AAC_HE,
- C2Config::PROFILE_AAC_HE_PS,
- C2Config::PROFILE_AAC_LD,
- C2Config::PROFILE_AAC_ELD}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_UNUSED
- })
- })
- .withSetter(ProfileLevelSetter)
- .build());
- }
-
- uint32_t getSampleRate() const { return mSampleRate->value; }
- uint32_t getChannelCount() const { return mChannelCount->value; }
- uint32_t getBitrate() const { return mBitrate->value; }
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::output> &me) {
- (void)mayBlock;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- static C2R MaxBufSizeCalculator(
- bool mayBlock,
- C2P<C2StreamMaxBufferSizeInfo::input> &me,
- const C2P<C2StreamChannelCountInfo::input> &channelCount) {
- (void)mayBlock;
- me.set().value = 1024 * sizeof(short) * channelCount.v.value;
- return C2R::Ok();
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
- std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
-};
-
-constexpr char COMPONENT_NAME[] = "c2.android.aac.encoder";
-
-C2SoftAacEnc::C2SoftAacEnc(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mAACEncoder(nullptr),
- mSBRMode(-1),
- mSBRRatio(0),
- mAACProfile(AOT_AAC_LC),
- mNumBytesPerInputFrame(0u),
- mOutBufferSize(0u),
- mSentCodecSpecificData(false),
- mInputSize(0),
- mInputTimeUs(-1ll),
- mSignalledError(false),
- mOutIndex(0u) {
-}
-
-C2SoftAacEnc::~C2SoftAacEnc() {
- onReset();
-}
-
-c2_status_t C2SoftAacEnc::onInit() {
- status_t err = initEncoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-status_t C2SoftAacEnc::initEncoder() {
- if (AACENC_OK != aacEncOpen(&mAACEncoder, 0, 0)) {
- ALOGE("Failed to init AAC encoder");
- return UNKNOWN_ERROR;
- }
- return setAudioParams();
-}
-
-c2_status_t C2SoftAacEnc::onStop() {
- mSentCodecSpecificData = false;
- mInputSize = 0u;
- mInputTimeUs = -1ll;
- mSignalledError = false;
- return C2_OK;
-}
-
-void C2SoftAacEnc::onReset() {
- (void)onStop();
- aacEncClose(&mAACEncoder);
-}
-
-void C2SoftAacEnc::onRelease() {
- // no-op
-}
-
-c2_status_t C2SoftAacEnc::onFlush_sm() {
- mSentCodecSpecificData = false;
- mInputSize = 0u;
- return C2_OK;
-}
-
-static CHANNEL_MODE getChannelMode(uint32_t nChannels) {
- CHANNEL_MODE chMode = MODE_INVALID;
- switch (nChannels) {
- case 1: chMode = MODE_1; break;
- case 2: chMode = MODE_2; break;
- case 3: chMode = MODE_1_2; break;
- case 4: chMode = MODE_1_2_1; break;
- case 5: chMode = MODE_1_2_2; break;
- case 6: chMode = MODE_1_2_2_1; break;
- default: chMode = MODE_INVALID;
- }
- return chMode;
-}
-
-//static AUDIO_OBJECT_TYPE getAOTFromProfile(OMX_U32 profile) {
-// if (profile == OMX_AUDIO_AACObjectLC) {
-// return AOT_AAC_LC;
-// } else if (profile == OMX_AUDIO_AACObjectHE) {
-// return AOT_SBR;
-// } else if (profile == OMX_AUDIO_AACObjectHE_PS) {
-// return AOT_PS;
-// } else if (profile == OMX_AUDIO_AACObjectLD) {
-// return AOT_ER_AAC_LD;
-// } else if (profile == OMX_AUDIO_AACObjectELD) {
-// return AOT_ER_AAC_ELD;
-// } else {
-// ALOGW("Unsupported AAC profile - defaulting to AAC-LC");
-// return AOT_AAC_LC;
-// }
-//}
-
-status_t C2SoftAacEnc::setAudioParams() {
- // We call this whenever sample rate, number of channels, bitrate or SBR mode change
- // in reponse to setParameter calls.
-
- ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio",
- mIntf->getSampleRate(), mIntf->getChannelCount(), mIntf->getBitrate(), mSBRMode, mSBRRatio);
-
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT, mAACProfile)) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
-
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SAMPLERATE, mIntf->getSampleRate())) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_BITRATE, mIntf->getBitrate())) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CHANNELMODE,
- getChannelMode(mIntf->getChannelCount()))) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_TRANSMUX, TT_MP4_RAW)) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
-
- if (mSBRMode != -1 && mAACProfile == AOT_ER_AAC_ELD) {
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, mSBRMode)) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
- }
-
- /* SBR ratio parameter configurations:
- 0: Default configuration wherein SBR ratio is configured depending on audio object type by
- the FDK.
- 1: Downsampled SBR (default for ELD)
- 2: Dualrate SBR (default for HE-AAC)
- */
- if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, mSBRRatio)) {
- ALOGE("Failed to set AAC encoder parameters");
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-void C2SoftAacEnc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError) {
- return;
- }
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-
- uint32_t sampleRate = mIntf->getSampleRate();
- uint32_t channelCount = mIntf->getChannelCount();
-
- if (!mSentCodecSpecificData) {
- // The very first thing we want to output is the codec specific
- // data.
-
- if (AACENC_OK != aacEncEncode(mAACEncoder, nullptr, nullptr, nullptr, nullptr)) {
- ALOGE("Unable to initialize encoder for profile / sample-rate / bit-rate / channels");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- uint32_t bitrate = mIntf->getBitrate();
- uint32_t actualBitRate = aacEncoder_GetParam(mAACEncoder, AACENC_BITRATE);
- if (bitrate != actualBitRate) {
- ALOGW("Requested bitrate %u unsupported, using %u", bitrate, actualBitRate);
- }
-
- AACENC_InfoStruct encInfo;
- if (AACENC_OK != aacEncInfo(mAACEncoder, &encInfo)) {
- ALOGE("Failed to get AAC encoder info");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- std::unique_ptr<C2StreamCsdInfo::output> csd =
- C2StreamCsdInfo::output::AllocUnique(encInfo.confSize, 0u);
- if (!csd) {
- ALOGE("CSD allocation failed");
- mSignalledError = true;
- work->result = C2_NO_MEMORY;
- return;
- }
- memcpy(csd->m.value, encInfo.confBuf, encInfo.confSize);
- ALOGV("put csd");
-#if defined(LOG_NDEBUG) && !LOG_NDEBUG
- hexdump(csd->m.value, csd->flexCount());
-#endif
- work->worklets.front()->output.configUpdate.push_back(std::move(csd));
-
- mOutBufferSize = encInfo.maxOutBufBytes;
- mNumBytesPerInputFrame = encInfo.frameLength * channelCount * sizeof(int16_t);
- mInputTimeUs = work->input.ordinal.timestamp;
-
- mSentCodecSpecificData = true;
- }
-
- uint8_t temp[1];
- C2ReadView view = mDummyReadView;
- const uint8_t *data = temp;
- size_t capacity = 0u;
- if (!work->input.buffers.empty()) {
- view = work->input.buffers[0]->data().linearBlocks().front().map().get();
- data = view.data();
- capacity = view.capacity();
- }
-
- size_t numFrames = (capacity + mInputSize + (eos ? mNumBytesPerInputFrame - 1 : 0))
- / mNumBytesPerInputFrame;
- ALOGV("capacity = %zu; mInputSize = %zu; numFrames = %zu mNumBytesPerInputFrame = %u",
- capacity, mInputSize, numFrames, mNumBytesPerInputFrame);
-
- std::shared_ptr<C2LinearBlock> block;
- std::shared_ptr<C2Buffer> buffer;
- std::unique_ptr<C2WriteView> wView;
- uint8_t *outPtr = temp;
- size_t outAvailable = 0u;
- uint64_t inputIndex = work->input.ordinal.frameIndex.peeku();
-
- AACENC_InArgs inargs;
- AACENC_OutArgs outargs;
- memset(&inargs, 0, sizeof(inargs));
- memset(&outargs, 0, sizeof(outargs));
- inargs.numInSamples = capacity / sizeof(int16_t);
-
- void* inBuffer[] = { (unsigned char *)data };
- INT inBufferIds[] = { IN_AUDIO_DATA };
- INT inBufferSize[] = { (INT)capacity };
- INT inBufferElSize[] = { sizeof(int16_t) };
-
- AACENC_BufDesc inBufDesc;
- inBufDesc.numBufs = sizeof(inBuffer) / sizeof(void*);
- inBufDesc.bufs = (void**)&inBuffer;
- inBufDesc.bufferIdentifiers = inBufferIds;
- inBufDesc.bufSizes = inBufferSize;
- inBufDesc.bufElSizes = inBufferElSize;
-
- void* outBuffer[] = { outPtr };
- INT outBufferIds[] = { OUT_BITSTREAM_DATA };
- INT outBufferSize[] = { 0 };
- INT outBufferElSize[] = { sizeof(UCHAR) };
-
- AACENC_BufDesc outBufDesc;
- outBufDesc.numBufs = sizeof(outBuffer) / sizeof(void*);
- outBufDesc.bufs = (void**)&outBuffer;
- outBufDesc.bufferIdentifiers = outBufferIds;
- outBufDesc.bufSizes = outBufferSize;
- outBufDesc.bufElSizes = outBufferElSize;
-
- AACENC_ERROR encoderErr = AACENC_OK;
-
- class FillWork {
- public:
- FillWork(uint32_t flags, C2WorkOrdinalStruct ordinal,
- const std::shared_ptr<C2Buffer> &buffer)
- : mFlags(flags), mOrdinal(ordinal), mBuffer(buffer) {
- }
- ~FillWork() = default;
-
- void operator()(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = (C2FrameData::flags_t)mFlags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = mOrdinal;
- work->workletsProcessed = 1u;
- work->result = C2_OK;
- if (mBuffer) {
- work->worklets.front()->output.buffers.push_back(mBuffer);
- }
- ALOGV("timestamp = %lld, index = %lld, w/%s buffer",
- mOrdinal.timestamp.peekll(),
- mOrdinal.frameIndex.peekll(),
- mBuffer ? "" : "o");
- }
-
- private:
- const uint32_t mFlags;
- const C2WorkOrdinalStruct mOrdinal;
- const std::shared_ptr<C2Buffer> mBuffer;
- };
-
- C2WorkOrdinalStruct outOrdinal = work->input.ordinal;
-
- while (encoderErr == AACENC_OK && inargs.numInSamples > 0) {
- if (numFrames && !block) {
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- // TODO: error handling, proper usage, etc.
- c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock failed : err = %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
-
- wView.reset(new C2WriteView(block->map().get()));
- outPtr = wView->data();
- outAvailable = wView->size();
- --numFrames;
- }
-
- memset(&outargs, 0, sizeof(outargs));
-
- outBuffer[0] = outPtr;
- outBufferSize[0] = outAvailable;
-
- encoderErr = aacEncEncode(mAACEncoder,
- &inBufDesc,
- &outBufDesc,
- &inargs,
- &outargs);
-
- if (encoderErr == AACENC_OK) {
- if (buffer) {
- outOrdinal.frameIndex = mOutIndex++;
- outOrdinal.timestamp = mInputTimeUs;
- cloneAndSend(
- inputIndex,
- work,
- FillWork(C2FrameData::FLAG_INCOMPLETE, outOrdinal, buffer));
- buffer.reset();
- }
-
- if (outargs.numOutBytes > 0) {
- mInputSize = 0;
- int consumed = (capacity / sizeof(int16_t)) - inargs.numInSamples
- + outargs.numInSamples;
- mInputTimeUs = work->input.ordinal.timestamp
- + (consumed * 1000000ll / channelCount / sampleRate);
- buffer = createLinearBuffer(block, 0, outargs.numOutBytes);
-#if defined(LOG_NDEBUG) && !LOG_NDEBUG
- hexdump(outPtr, std::min(outargs.numOutBytes, 256));
-#endif
- outPtr = temp;
- outAvailable = 0;
- block.reset();
- } else {
- mInputSize += outargs.numInSamples * sizeof(int16_t);
- }
-
- if (outargs.numInSamples > 0) {
- inBuffer[0] = (int16_t *)inBuffer[0] + outargs.numInSamples;
- inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
- inargs.numInSamples -= outargs.numInSamples;
- }
- }
- ALOGV("encoderErr = %d mInputSize = %zu inargs.numInSamples = %d, mInputTimeUs = %lld",
- encoderErr, mInputSize, inargs.numInSamples, mInputTimeUs.peekll());
- }
-
- if (eos && inBufferSize[0] > 0) {
- if (numFrames && !block) {
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- // TODO: error handling, proper usage, etc.
- c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock failed : err = %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
-
- wView.reset(new C2WriteView(block->map().get()));
- outPtr = wView->data();
- outAvailable = wView->size();
- --numFrames;
- }
-
- memset(&outargs, 0, sizeof(outargs));
-
- outBuffer[0] = outPtr;
- outBufferSize[0] = outAvailable;
-
- // Flush
- inargs.numInSamples = -1;
-
- (void)aacEncEncode(mAACEncoder,
- &inBufDesc,
- &outBufDesc,
- &inargs,
- &outargs);
- }
-
- outOrdinal.frameIndex = mOutIndex++;
- outOrdinal.timestamp = mInputTimeUs;
- FillWork((C2FrameData::flags_t)(eos ? C2FrameData::FLAG_END_OF_STREAM : 0),
- outOrdinal, buffer)(work);
-}
-
-c2_status_t C2SoftAacEnc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- switch (drainMode) {
- case DRAIN_COMPONENT_NO_EOS:
- [[fallthrough]];
- case NO_DRAIN:
- // no-op
- return C2_OK;
- case DRAIN_CHAIN:
- return C2_OMITTED;
- case DRAIN_COMPONENT_WITH_EOS:
- break;
- default:
- return C2_BAD_VALUE;
- }
-
- (void)pool;
- mSentCodecSpecificData = false;
- mInputSize = 0u;
-
- // TODO: we don't have any pending work at this time to drain.
- return C2_OK;
-}
-
-class C2SoftAacEncFactory : public C2ComponentFactory {
-public:
- C2SoftAacEncFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAacEnc(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftAacEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAacEnc::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftAacEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAacEncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAacEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/aac/C2SoftAacEnc.h b/media/codecs/aac/C2SoftAacEnc.h
deleted file mode 100644
index 82fb438..0000000
--- a/media/codecs/aac/C2SoftAacEnc.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AAC_ENC_H_
-#define ANDROID_C2_SOFT_AAC_ENC_H_
-
-#include <atomic>
-
-#include <SimpleC2Component.h>
-
-#include "aacenc_lib.h"
-
-namespace android {
-
-class C2SoftAacEnc : public SimpleC2Component {
-public:
- class IntfImpl;
-
- C2SoftAacEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftAacEnc();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- std::shared_ptr<IntfImpl> mIntf;
-
- HANDLE_AACENCODER mAACEncoder;
-
- int32_t mSBRMode;
- int32_t mSBRRatio;
- AUDIO_OBJECT_TYPE mAACProfile;
- UINT mNumBytesPerInputFrame;
- UINT mOutBufferSize;
-
- bool mSentCodecSpecificData;
- size_t mInputSize;
- c2_cntr64_t mInputTimeUs;
-
- bool mSignalledError;
- std::atomic_uint64_t mOutIndex;
-
- status_t initEncoder();
-
- status_t setAudioParams();
-
- C2_DO_NOT_COPY(C2SoftAacEnc);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AAC_ENC_H_
diff --git a/media/codecs/aac/DrcPresModeWrap.cpp b/media/codecs/aac/DrcPresModeWrap.cpp
deleted file mode 100644
index 5b9aebc..0000000
--- a/media/codecs/aac/DrcPresModeWrap.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-#include "DrcPresModeWrap.h"
-
-#include <assert.h>
-
-#define LOG_TAG "C2SoftAacDrcWrapper"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-//#define DRC_PRES_MODE_WRAP_DEBUG
-
-#define GPM_ENCODER_TARGET_LEVEL 64
-#define MAX_TARGET_LEVEL 40
-
-CDrcPresModeWrapper::CDrcPresModeWrapper()
-{
- mDataUpdate = true;
-
- /* Data from streamInfo. */
- /* Initialized to the same values as in the aac decoder */
- mStreamPRL = -1;
- mStreamDRCPresMode = -1;
- mStreamNrAACChan = 0;
- mStreamNrOutChan = 0;
-
- /* Desired values (set by user). */
- /* Initialized to the same values as in the aac decoder */
- mDesTarget = -1;
- mDesAttFactor = 0;
- mDesBoostFactor = 0;
- mDesHeavy = 0;
-
- mEncoderTarget = -1;
-
- /* Values from last time. */
- /* Initialized to the same values as the desired values */
- mLastTarget = -1;
- mLastAttFactor = 0;
- mLastBoostFactor = 0;
- mLastHeavy = 0;
-}
-
-CDrcPresModeWrapper::~CDrcPresModeWrapper()
-{
-}
-
-void
-CDrcPresModeWrapper::setDecoderHandle(const HANDLE_AACDECODER handle)
-{
- mHandleDecoder = handle;
-}
-
-void
-CDrcPresModeWrapper::submitStreamData(CStreamInfo* pStreamInfo)
-{
- assert(pStreamInfo);
-
- if (mStreamPRL != pStreamInfo->drcProgRefLev) {
- mStreamPRL = pStreamInfo->drcProgRefLev;
- mDataUpdate = true;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- ALOGV("DRC presentation mode wrapper: drcProgRefLev is %d\n", mStreamPRL);
-#endif
- }
-
- if (mStreamDRCPresMode != pStreamInfo->drcPresMode) {
- mStreamDRCPresMode = pStreamInfo->drcPresMode;
- mDataUpdate = true;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- ALOGV("DRC presentation mode wrapper: drcPresMode is %d\n", mStreamDRCPresMode);
-#endif
- }
-
- if (mStreamNrAACChan != pStreamInfo->aacNumChannels) {
- mStreamNrAACChan = pStreamInfo->aacNumChannels;
- mDataUpdate = true;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- ALOGV("DRC presentation mode wrapper: aacNumChannels is %d\n", mStreamNrAACChan);
-#endif
- }
-
- if (mStreamNrOutChan != pStreamInfo->numChannels) {
- mStreamNrOutChan = pStreamInfo->numChannels;
- mDataUpdate = true;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- ALOGV("DRC presentation mode wrapper: numChannels is %d\n", mStreamNrOutChan);
-#endif
- }
-
-
-
- if (mStreamNrOutChan<mStreamNrAACChan) {
- mIsDownmix = true;
- } else {
- mIsDownmix = false;
- }
-
- if (mIsDownmix && (mStreamNrOutChan == 1)) {
- mIsMonoDownmix = true;
- } else {
- mIsMonoDownmix = false;
- }
-
- if (mIsDownmix && mStreamNrOutChan == 2){
- mIsStereoDownmix = true;
- } else {
- mIsStereoDownmix = false;
- }
-
-}
-
-void
-CDrcPresModeWrapper::setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value)
-{
- switch (param) {
- case DRC_PRES_MODE_WRAP_DESIRED_TARGET:
- mDesTarget = value;
- break;
- case DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR:
- mDesAttFactor = value;
- break;
- case DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR:
- mDesBoostFactor = value;
- break;
- case DRC_PRES_MODE_WRAP_DESIRED_HEAVY:
- mDesHeavy = value;
- break;
- case DRC_PRES_MODE_WRAP_ENCODER_TARGET:
- mEncoderTarget = value;
- break;
- default:
- break;
- }
- mDataUpdate = true;
-}
-
-void
-CDrcPresModeWrapper::update()
-{
- // Get Data from Decoder
- int progRefLevel = mStreamPRL;
- int drcPresMode = mStreamDRCPresMode;
-
- // by default, do as desired
- int newTarget = mDesTarget;
- int newAttFactor = mDesAttFactor;
- int newBoostFactor = mDesBoostFactor;
- int newHeavy = mDesHeavy;
-
- if (mDataUpdate) {
- // sanity check
- if (mDesTarget < MAX_TARGET_LEVEL){
- mDesTarget = MAX_TARGET_LEVEL; // limit target level to -10 dB or below
- newTarget = MAX_TARGET_LEVEL;
- }
-
- if (mEncoderTarget != -1) {
- if (mDesTarget<124) { // if target level > -31 dB
- if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
- // no stereo or mono downmixing, calculated scaling of light DRC
- /* use as little compression as possible */
- newAttFactor = 0;
- newBoostFactor = 0;
- if (mDesTarget<progRefLevel) { // if target level > PRL
- if (mEncoderTarget < mDesTarget) { // if mEncoderTarget > target level
- // mEncoderTarget > target level > PRL
- int calcFactor;
- float calcFactor_norm;
- // 0.0f < calcFactor_norm < 1.0f
- calcFactor_norm = (float)(mDesTarget - progRefLevel) /
- (float)(mEncoderTarget - progRefLevel);
- calcFactor = (int)(calcFactor_norm*127.0f); // 0 <= calcFactor < 127
- // calcFactor is the lower limit
- newAttFactor = (calcFactor>newAttFactor) ? calcFactor : newAttFactor;
- // new AttFactor will be always = calcFactor, as it is set to 0 before.
- newBoostFactor = newAttFactor;
- } else {
- /* target level > mEncoderTarget > PRL */
- // newTDLimiterEnable = 1;
- // the time domain limiter must always be active in this case.
- // It is assumed that the framework activates it by default
- newAttFactor = 127;
- newBoostFactor = 127;
- }
- } else { // target level <= PRL
- // no restrictions required
- // newAttFactor = newAttFactor;
- }
- } else { // downmixing
- // if target level > -23 dB or mono downmix
- if ( (mDesTarget<92) || mIsMonoDownmix ) {
- newHeavy = 1;
- } else {
- // we perform a downmix, so, we need at least full light DRC
- newAttFactor = 127;
- }
- }
- } else { // target level <= -31 dB
- // playback -31 dB: light DRC only needed if we perform downmixing
- if (mIsDownmix) { // we do downmixing
- newAttFactor = 127;
- }
- }
- }
- else { // handle other used encoder target levels
-
- // Sanity check: DRC presentation mode is only specified for max. 5.1 channels
- if (mStreamNrAACChan > 6) {
- drcPresMode = 0;
- }
-
- switch (drcPresMode) {
- case 0:
- default: // presentation mode not indicated
- {
-
- if (mDesTarget<124) { // if target level > -31 dB
- // no stereo or mono downmixing
- if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
- if (mDesTarget<progRefLevel) { // if target level > PRL
- // newTDLimiterEnable = 1;
- // the time domain limiter must always be active in this case.
- // It is assumed that the framework activates it by default
- newAttFactor = 127; // at least, use light compression
- } else { // target level <= PRL
- // no restrictions required
- // newAttFactor = newAttFactor;
- }
- } else { // downmixing
- // newTDLimiterEnable = 1;
- // the time domain limiter must always be active in this case.
- // It is assumed that the framework activates it by default
-
- // if target level > -23 dB or mono downmix
- if ( (mDesTarget < 92) || mIsMonoDownmix ) {
- newHeavy = 1;
- } else{
- // we perform a downmix, so, we need at least full light DRC
- newAttFactor = 127;
- }
- }
- } else { // target level <= -31 dB
- if (mIsDownmix) { // we do downmixing.
- // newTDLimiterEnable = 1;
- // the time domain limiter must always be active in this case.
- // It is assumed that the framework activates it by default
- newAttFactor = 127;
- }
- }
- }
- break;
-
- // Presentation mode 1 and 2 according to ETSI TS 101 154:
- // Digital Video Broadcasting (DVB); Specification for the use of Video and Audio Coding
- // in Broadcasting Applications based on the MPEG-2 Transport Stream,
- // section C.5.4., "Decoding", and Table C.33
- // ISO DRC -> newHeavy = 0 (Use light compression, MPEG-style)
- // Compression_value -> newHeavy = 1 (Use heavy compression, DVB-style)
- // scaling restricted -> newAttFactor = 127
-
- case 1: // presentation mode 1, Light:-31/Heavy:-23
- {
- if (mDesTarget < 124) { // if target level > -31 dB
- // playback up to -23 dB
- newHeavy = 1;
- } else { // target level <= -31 dB
- // playback -31 dB
- if (mIsDownmix) { // we do downmixing.
- newAttFactor = 127;
- }
- }
- }
- break;
-
- case 2: // presentation mode 2, Light:-23/Heavy:-23
- {
- if (mDesTarget < 124) { // if target level > -31 dB
- // playback up to -23 dB
- if (mIsMonoDownmix) { // if mono downmix
- newHeavy = 1;
- } else {
- newHeavy = 0;
- newAttFactor = 127;
- }
- } else { // target level <= -31 dB
- // playback -31 dB
- newHeavy = 0;
- if (mIsDownmix) { // we do downmixing.
- newAttFactor = 127;
- }
- }
- }
- break;
-
- } // switch()
- } // if (mEncoderTarget == GPM_ENCODER_TARGET_LEVEL)
-
- // sanity again
- if (newHeavy == 1) {
- newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
- newAttFactor = 127;
- }
-
- // update the decoder
- if (newTarget != mLastTarget) {
- aacDecoder_SetParam(mHandleDecoder, AAC_DRC_REFERENCE_LEVEL, newTarget);
- mLastTarget = newTarget;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- if (newTarget != mDesTarget)
- ALOGV("DRC presentation mode wrapper: forced target level to %d (from %d)\n", newTarget, mDesTarget);
- else
- ALOGV("DRC presentation mode wrapper: set target level to %d\n", newTarget);
-#endif
- }
-
- if (newAttFactor != mLastAttFactor) {
- aacDecoder_SetParam(mHandleDecoder, AAC_DRC_ATTENUATION_FACTOR, newAttFactor);
- mLastAttFactor = newAttFactor;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- if (newAttFactor != mDesAttFactor)
- ALOGV("DRC presentation mode wrapper: forced attenuation factor to %d (from %d)\n", newAttFactor, mDesAttFactor);
- else
- ALOGV("DRC presentation mode wrapper: set attenuation factor to %d\n", newAttFactor);
-#endif
- }
-
- if (newBoostFactor != mLastBoostFactor) {
- aacDecoder_SetParam(mHandleDecoder, AAC_DRC_BOOST_FACTOR, newBoostFactor);
- mLastBoostFactor = newBoostFactor;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- if (newBoostFactor != mDesBoostFactor)
- ALOGV("DRC presentation mode wrapper: forced boost factor to %d (from %d)\n",
- newBoostFactor, mDesBoostFactor);
- else
- ALOGV("DRC presentation mode wrapper: set boost factor to %d\n", newBoostFactor);
-#endif
- }
-
- if (newHeavy != mLastHeavy) {
- aacDecoder_SetParam(mHandleDecoder, AAC_DRC_HEAVY_COMPRESSION, newHeavy);
- mLastHeavy = newHeavy;
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- if (newHeavy != mDesHeavy)
- ALOGV("DRC presentation mode wrapper: forced heavy compression to %d (from %d)\n",
- newHeavy, mDesHeavy);
- else
- ALOGV("DRC presentation mode wrapper: set heavy compression to %d\n", newHeavy);
-#endif
- }
-
-#ifdef DRC_PRES_MODE_WRAP_DEBUG
- ALOGV("DRC config: tgt_lev: %3d, cut: %3d, boost: %3d, heavy: %d\n", newTarget,
- newAttFactor, newBoostFactor, newHeavy);
-#endif
- mDataUpdate = false;
-
- } // if (mDataUpdate)
-}
diff --git a/media/codecs/aac/DrcPresModeWrap.h b/media/codecs/aac/DrcPresModeWrap.h
deleted file mode 100644
index f0b6cf2..0000000
--- a/media/codecs/aac/DrcPresModeWrap.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-#pragma once
-#include "aacdecoder_lib.h"
-
-typedef enum
-{
- DRC_PRES_MODE_WRAP_DESIRED_TARGET = 0x0000,
- DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR = 0x0001,
- DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR = 0x0002,
- DRC_PRES_MODE_WRAP_DESIRED_HEAVY = 0x0003,
- DRC_PRES_MODE_WRAP_ENCODER_TARGET = 0x0004
-} DRC_PRES_MODE_WRAP_PARAM;
-
-
-class CDrcPresModeWrapper {
-public:
- CDrcPresModeWrapper();
- ~CDrcPresModeWrapper();
- void setDecoderHandle(const HANDLE_AACDECODER handle);
- void setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value);
- void submitStreamData(CStreamInfo*);
- void update();
-
-protected:
- HANDLE_AACDECODER mHandleDecoder;
- int mDesTarget;
- int mDesAttFactor;
- int mDesBoostFactor;
- int mDesHeavy;
-
- int mEncoderTarget;
-
- int mLastTarget;
- int mLastAttFactor;
- int mLastBoostFactor;
- int mLastHeavy;
-
- SCHAR mStreamPRL;
- SCHAR mStreamDRCPresMode;
- INT mStreamNrAACChan;
- INT mStreamNrOutChan;
-
- bool mIsDownmix;
- bool mIsMonoDownmix;
- bool mIsStereoDownmix;
-
- bool mDataUpdate;
-};
diff --git a/media/codecs/aac/MODULE_LICENSE_APACHE2 b/media/codecs/aac/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/aac/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/aac/NOTICE b/media/codecs/aac/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/aac/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/aac/patent_disclaimer.txt b/media/codecs/aac/patent_disclaimer.txt
deleted file mode 100644
index b4bf11d..0000000
--- a/media/codecs/aac/patent_disclaimer.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-THIS IS NOT A GRANT OF PATENT RIGHTS.
-
-Google makes no representation or warranty that the codecs for which
-source code is made available hereunder are unencumbered by
-third-party patents. Those intending to use this source code in
-hardware or software products are advised that implementations of
-these codecs, including in open source software or shareware, may
-require patent licenses from the relevant patent holders.
diff --git a/media/codecs/amr_nb_wb/Android.bp b/media/codecs/amr_nb_wb/Android.bp
deleted file mode 100644
index 764b3db..0000000
--- a/media/codecs/amr_nb_wb/Android.bp
+++ /dev/null
@@ -1,77 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2amrnbdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftAmrDec.cpp"],
-
- cflags: [
- "-DAMRNB",
- ],
-
- static_libs: [
- "libstagefright_amrnbdec",
- "libstagefright_amrwbdec",
- ],
-
- shared_libs: [
- "libstagefright_amrnb_common",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2amrwbdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftAmrDec.cpp"],
-
- static_libs: [
- "libstagefright_amrnbdec",
- "libstagefright_amrwbdec",
- ],
-
- shared_libs: [
- "libstagefright_amrnb_common",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2amrnbenc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftAmrNbEnc.cpp"],
-
- static_libs: [
- "libstagefright_amrnbenc",
- ],
-
- shared_libs: [
- "libstagefright_amrnb_common",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2amrwbenc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftAmrWbEnc.cpp"],
-
- static_libs: [
- "libstagefright_amrwbenc",
- ],
-
- shared_libs: [
- "libstagefright_enc_common",
- ],
-}
diff --git a/media/codecs/amr_nb_wb/C2SoftAmrDec.cpp b/media/codecs/amr_nb_wb/C2SoftAmrDec.cpp
deleted file mode 100644
index c591e21..0000000
--- a/media/codecs/amr_nb_wb/C2SoftAmrDec.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 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
-#ifdef AMRNB
-#define LOG_TAG "C2SoftAmrNbDec"
-#else
-#define LOG_TAG "C2SoftAmrWbDec"
-#endif
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftAmrDec.h"
-#include "gsmamr_dec.h"
-#include "pvamrwbdecoder.h"
-
-namespace android {
-
-#ifdef AMRNB
- constexpr char COMPONENT_NAME[] = "c2.android.amrnb.decoder";
-#else
- constexpr char COMPONENT_NAME[] = "c2.android.amrwb.decoder";
-#endif
-
-class C2SoftAmrDec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
-#ifdef AMRNB
- MEDIA_MIMETYPE_AUDIO_AMR_NB
-#else
- MEDIA_MIMETYPE_AUDIO_AMR_WB
-#endif
- )).build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
-#ifdef AMRNB
- .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
- .withFields({C2F(mSampleRate, value).equalTo(8000)})
-#else
- .withDefault(new C2StreamSampleRateInfo::output(0u, 16000))
- .withFields({C2F(mSampleRate, value).equalTo(16000)})
-#endif
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).equalTo(1)})
- .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
-#ifdef AMRNB
- .withDefault(new C2BitrateTuning::input(0u, 4750))
- .withFields({C2F(mBitrate, value).inRange(4750, 12200)})
-#else
- .withDefault(new C2BitrateTuning::input(0u, 6600))
- .withFields({C2F(mBitrate, value).inRange(6600, 23850)})
-#endif
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftAmrDec::C2SoftAmrDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mAmrHandle(nullptr),
- mDecoderBuf(nullptr),
- mDecoderCookie(nullptr) {
-#ifdef AMRNB
- mIsWide = false;
-#else
- mIsWide = true;
-#endif
-}
-
-C2SoftAmrDec::~C2SoftAmrDec() {
- (void)onRelease();
-}
-
-c2_status_t C2SoftAmrDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftAmrDec::onStop() {
- if (!mIsWide) {
- Speech_Decode_Frame_reset(mAmrHandle);
- } else {
- pvDecoder_AmrWb_Reset(mAmrHandle, 0 /* reset_all */);
- }
- mSignalledError = false;
- mSignalledOutputEos = false;
-
- return C2_OK;
-}
-
-void C2SoftAmrDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftAmrDec::onRelease() {
- if (!mIsWide) {
- if (mAmrHandle) {
- GSMDecodeFrameExit(&mAmrHandle);
- }
- mAmrHandle = nullptr;
- } else {
- if (mDecoderBuf) {
- free(mDecoderBuf);
- }
- mDecoderBuf = nullptr;
- mAmrHandle = nullptr;
- mDecoderCookie = nullptr;
- }
-}
-
-c2_status_t C2SoftAmrDec::onFlush_sm() {
- return onStop();
-}
-
-status_t C2SoftAmrDec::initDecoder() {
- if (!mIsWide) {
- if (GSMInitDecode(&mAmrHandle, (int8_t *)"AMRNBDecoder"))
- return UNKNOWN_ERROR;
- } else {
- uint32_t memReq = pvDecoder_AmrWbMemRequirements();
- mDecoderBuf = malloc(memReq);
- if (mDecoderBuf) {
- pvDecoder_AmrWb_Init(&mAmrHandle, mDecoderBuf, &mDecoderCookie);
- }
- else {
- return NO_MEMORY;
- }
- }
- mSignalledError = false;
- mSignalledOutputEos = false;
-
- return OK;
-}
-
-static size_t getFrameSize(bool isWide, unsigned FM) {
- static const size_t kFrameSizeNB[16] = {
- 12, 13, 15, 17, 19, 20, 26, 31,
- 5, 6, 5, 5, // SID
- 0, 0, 0, // future use
- 0 // no data
- };
- static const size_t kFrameSizeWB[16] = {
- 17, 23, 32, 36, 40, 46, 50, 58, 60,
- 5, // SID
- 0, 0, 0, 0, // future use
- 0, // speech lost
- 0 // no data
- };
-
- if (FM > 15 || (isWide && FM > 9 && FM < 14) || (!isWide && FM > 11 && FM < 15)) {
- ALOGE("illegal AMR frame mode %d", FM);
- return 0;
- }
- // add 1 for header byte
- return (isWide ? kFrameSizeWB[FM] : kFrameSizeNB[FM]) + 1;
-}
-
-static status_t calculateNumFrames(const uint8 *input, size_t inSize,
- std::vector<size_t> *frameSizeList, bool isWide) {
- for (size_t k = 0; k < inSize;) {
- int16_t FM = ((input[0] >> 3) & 0x0f);
- size_t frameSize = getFrameSize(isWide, FM);
- if (frameSize == 0) {
- return UNKNOWN_ERROR;
- }
- if ((inSize - k) >= frameSize) {
- input += frameSize;
- k += frameSize;
- }
- else break;
- frameSizeList->push_back(frameSize);
- }
- return OK;
-}
-
-void C2SoftAmrDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- C2ReadView rView = mDummyReadView;
- size_t inOffset = 0u;
- size_t inSize = 0u;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
-
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
- if (inSize == 0) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
- std::vector<size_t> frameSizeList;
- if (OK != calculateNumFrames(rView.data() + inOffset, inSize, &frameSizeList,
- mIsWide)) {
- work->result = C2_CORRUPTED;
- mSignalledError = true;
- return;
- }
- if (frameSizeList.empty()) {
- ALOGE("input size smaller than expected");
- work->result = C2_CORRUPTED;
- mSignalledError = true;
- return;
- }
-
- int16_t outSamples = mIsWide ? kNumSamplesPerFrameWB : kNumSamplesPerFrameNB;
- size_t calOutSize = outSamples * frameSizeList.size() * sizeof(int16_t);
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
-
- int16_t *output = reinterpret_cast<int16_t *>(wView.data());
- auto it = frameSizeList.begin();
- const uint8_t *inPtr = rView.data() + inOffset;
- size_t inPos = 0;
- while (inPos < inSize) {
- if (it == frameSizeList.end()) {
- ALOGD("unexpected trailing bytes, ignoring them");
- break;
- }
- uint8_t *input = const_cast<uint8_t *>(inPtr + inPos);
- int16_t FM = ((*input >> 3) & 0x0f);
- if (!mIsWide) {
- int32_t numBytesRead = AMRDecode(mAmrHandle,
- (Frame_Type_3GPP) FM,
- input + 1, output, MIME_IETF);
- if (static_cast<size_t>(numBytesRead + 1) != *it) {
- ALOGE("panic, parsed size does not match decoded size");
- work->result = C2_CORRUPTED;
- mSignalledError = true;
- return;
- }
- } else {
- if (FM >= 9) {
- // Produce silence instead of comfort noise and for
- // speech lost/no data.
- memset(output, 0, outSamples * sizeof(int16_t));
- } else {
- int16_t FT;
- RX_State_wb rx_state;
- int16_t numRecSamples;
-
- mime_unsorting(const_cast<uint8_t *>(&input[1]),
- mInputSampleBuffer, &FT, &FM, 1, &rx_state);
- pvDecoder_AmrWb(FM, mInputSampleBuffer, output, &numRecSamples,
- mDecoderBuf, FT, mDecoderCookie);
- if (numRecSamples != outSamples) {
- ALOGE("Sample output per frame incorrect");
- work->result = C2_CORRUPTED;
- mSignalledError = true;
- return;
- }
- /* Delete the 2 LSBs (14-bit output) */
- for (int i = 0; i < numRecSamples; ++i) {
- output[i] &= 0xfffC;
- }
- }
- }
- inPos += *it;
- output += outSamples;
- ++it;
- }
-
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-c2_status_t C2SoftAmrDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void)pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
- return C2_OK;
-}
-
-class C2SoftAMRDecFactory : public C2ComponentFactory {
-public:
- C2SoftAMRDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAmrDec(COMPONENT_NAME, id,
- std::make_shared<C2SoftAmrDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAmrDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftAmrDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAMRDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAMRDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/amr_nb_wb/C2SoftAmrDec.h b/media/codecs/amr_nb_wb/C2SoftAmrDec.h
deleted file mode 100644
index 6384450..0000000
--- a/media/codecs/amr_nb_wb/C2SoftAmrDec.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AMR_DEC_H_
-#define ANDROID_C2_SOFT_AMR_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-namespace android {
-
-struct C2SoftAmrDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftAmrDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftAmrDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-private:
- enum {
- kNumSamplesPerFrameNB = 160,
- kNumSamplesPerFrameWB = 320,
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- void *mAmrHandle;
- void *mDecoderBuf;
- int16_t *mDecoderCookie;
-
- int16_t mInputSampleBuffer[477];
-
- bool mIsWide;
- bool mSignalledError;
- bool mSignalledOutputEos;
-
- status_t initDecoder();
-
- C2_DO_NOT_COPY(C2SoftAmrDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AMR_DEC_H_
diff --git a/media/codecs/amr_nb_wb/C2SoftAmrNbEnc.cpp b/media/codecs/amr_nb_wb/C2SoftAmrNbEnc.cpp
deleted file mode 100644
index ca21480..0000000
--- a/media/codecs/amr_nb_wb/C2SoftAmrNbEnc.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftAmrNbEnc"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftAmrNbEnc.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.amrnb.encoder";
-
-class C2SoftAmrNbEnc::IntfImpl : public C2InterfaceHelper {
- public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::input(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_AMR_NB))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
- .withFields({C2F(mChannelCount, value).equalTo(1)})
- .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::input(0u, 8000))
- .withFields({C2F(mSampleRate, value).equalTo(8000)})
- .withSetter(
- (Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 4750))
- .withFields({C2F(mBitrate, value).inRange(4750, 12200)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
- }
-
- uint32_t getSampleRate() const { return mSampleRate->value; }
- uint32_t getChannelCount() const { return mChannelCount->value; }
- uint32_t getBitrate() const { return mBitrate->value; }
-
- private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftAmrNbEnc::C2SoftAmrNbEnc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : SimpleC2Component(
- std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mEncState(nullptr),
- mSidState(nullptr) {
-}
-
-C2SoftAmrNbEnc::~C2SoftAmrNbEnc() {
- onRelease();
-}
-
-c2_status_t C2SoftAmrNbEnc::onInit() {
- bool dtx_enable = false;
-
- if (AMREncodeInit(&mEncState, &mSidState, dtx_enable) != 0)
- return C2_CORRUPTED;
- // TODO: get mode directly from config
- switch(mIntf->getBitrate()) {
- case 4750: mMode = MR475;
- break;
- case 5150: mMode = MR515;
- break;
- case 5900: mMode = MR59;
- break;
- case 6700: mMode = MR67;
- break;
- case 7400: mMode = MR74;
- break;
- case 7950: mMode = MR795;
- break;
- case 10200: mMode = MR102;
- break;
- case 12200: mMode = MR122;
- break;
- default: mMode = MR795;
- }
- mIsFirst = true;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mAnchorTimeStamp = 0;
- mProcessedSamples = 0;
- mFilledLen = 0;
-
- return C2_OK;
-}
-
-void C2SoftAmrNbEnc::onRelease() {
- if (mEncState) {
- AMREncodeExit(&mEncState, &mSidState);
- mEncState = mSidState = nullptr;
- }
-}
-
-c2_status_t C2SoftAmrNbEnc::onStop() {
- if (AMREncodeReset(mEncState, mSidState) != 0)
- return C2_CORRUPTED;
- mIsFirst = true;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mAnchorTimeStamp = 0;
- mProcessedSamples = 0;
- mFilledLen = 0;
-
- return C2_OK;
-}
-
-void C2SoftAmrNbEnc::onReset() {
- (void) onStop();
-}
-
-c2_status_t C2SoftAmrNbEnc::onFlush_sm() {
- return onStop();
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftAmrNbEnc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- size_t inOffset = 0u;
- size_t inSize = 0u;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
- size_t outCapacity = kNumBytesPerInputFrame;
- outCapacity += mFilledLen + inSize;
- std::shared_ptr<C2LinearBlock> outputBlock;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &outputBlock);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = outputBlock->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- uint64_t outTimeStamp =
- mProcessedSamples * 1000000ll / mIntf->getSampleRate();
- size_t inPos = 0;
- size_t outPos = 0;
- while (inPos < inSize) {
- const uint8_t *inPtr = rView.data() + inOffset;
- int validSamples = mFilledLen / sizeof(int16_t);
- if ((inPos + (kNumBytesPerInputFrame - mFilledLen)) <= inSize) {
- memcpy(mInputFrame + validSamples, inPtr + inPos,
- (kNumBytesPerInputFrame - mFilledLen));
- inPos += (kNumBytesPerInputFrame - mFilledLen);
- } else {
- memcpy(mInputFrame + validSamples, inPtr + inPos, (inSize - inPos));
- mFilledLen += (inSize - inPos);
- inPos += (inSize - inPos);
- if (eos) {
- validSamples = mFilledLen / sizeof(int16_t);
- memset(mInputFrame + validSamples, 0, (kNumBytesPerInputFrame - mFilledLen));
- } else break;
-
- }
- Frame_Type_3GPP frameType;
- int numEncBytes = AMREncode(mEncState, mSidState, mMode, mInputFrame,
- wView.data() + outPos, &frameType,
- AMR_TX_WMF);
- if (numEncBytes < 0 || numEncBytes > ((int)outCapacity - (int)outPos)) {
- ALOGE("encodeFrame call failed, state [%d %zu %zu]", numEncBytes, outPos, outCapacity);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- // Convert header byte from WMF to IETF format.
- if (numEncBytes > 0)
- wView.data()[outPos] = ((wView.data()[outPos] << 3) | 4) & 0x7c;
- outPos += numEncBytes;
- mProcessedSamples += kNumSamplesPerFrame;
- mFilledLen = 0;
- }
- ALOGV("causal sample size %d", mFilledLen);
- if (mIsFirst) {
- mIsFirst = false;
- mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
- }
- fillEmptyWork(work);
- if (outPos != 0) {
- work->worklets.front()->output.buffers.push_back(
- createLinearBuffer(std::move(outputBlock), 0, outPos));
- work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
-
- }
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- if (mFilledLen) ALOGV("Discarding trailing %d bytes", mFilledLen);
- }
-}
-
-c2_status_t C2SoftAmrNbEnc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- onFlush_sm();
- return C2_OK;
-}
-
-class C2SoftAmrNbEncFactory : public C2ComponentFactory {
-public:
- C2SoftAmrNbEncFactory()
- : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {}
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAmrNbEnc(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftAmrNbEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAmrNbEnc::IntfImpl>(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftAmrNbEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAmrNbEncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAmrNbEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/amr_nb_wb/C2SoftAmrNbEnc.h b/media/codecs/amr_nb_wb/C2SoftAmrNbEnc.h
deleted file mode 100644
index 6ab14db..0000000
--- a/media/codecs/amr_nb_wb/C2SoftAmrNbEnc.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AMR_NB_ENC_H_
-#define ANDROID_C2_SOFT_AMR_NB_ENC_H_
-
-#include <SimpleC2Component.h>
-
-#include "gsmamr_enc.h"
-
-namespace android {
-
-class C2SoftAmrNbEnc : public SimpleC2Component {
- public:
- class IntfImpl;
- C2SoftAmrNbEnc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftAmrNbEnc();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- std::shared_ptr<IntfImpl> mIntf;
- static const int32_t kNumSamplesPerFrame = L_FRAME;
- static const int32_t kNumBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
-
- void *mEncState;
- void *mSidState;
- Mode mMode;
- bool mIsFirst;
- bool mSignalledError;
- bool mSignalledOutputEos;
- uint64_t mAnchorTimeStamp;
- uint64_t mProcessedSamples;
- int32_t mFilledLen;
- int16_t mInputFrame[kNumSamplesPerFrame];
-
- C2_DO_NOT_COPY(C2SoftAmrNbEnc);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AMR_NB_ENC_H_
diff --git a/media/codecs/amr_nb_wb/C2SoftAmrWbEnc.cpp b/media/codecs/amr_nb_wb/C2SoftAmrWbEnc.cpp
deleted file mode 100644
index be3892f..0000000
--- a/media/codecs/amr_nb_wb/C2SoftAmrWbEnc.cpp
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftAmrWbEnc"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftAmrWbEnc.h"
-#include "cmnMemory.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.amrwb.encoder";
-
-class C2SoftAmrWbEnc::IntfImpl : public C2InterfaceHelper {
- public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::input(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_AMR_WB))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
- .withFields({C2F(mChannelCount, value).equalTo(1)})
- .withSetter((Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::input(0u, 16000))
- .withFields({C2F(mSampleRate, value).equalTo(16000)})
- .withSetter(
- (Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 6600))
- .withFields({C2F(mBitrate, value).inRange(6600, 23850)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
- }
-
- uint32_t getSampleRate() const { return mSampleRate->value; }
- uint32_t getChannelCount() const { return mChannelCount->value; }
- uint32_t getBitrate() const { return mBitrate->value; }
-
- private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftAmrWbEnc::C2SoftAmrWbEnc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : SimpleC2Component(
- std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mEncoderHandle(nullptr),
- mApiHandle(nullptr),
- mMemOperator(nullptr) {
-}
-
-C2SoftAmrWbEnc::~C2SoftAmrWbEnc() {
- onRelease();
-}
-
-c2_status_t C2SoftAmrWbEnc::onInit() {
- // TODO: get mode directly from config
- switch(mIntf->getBitrate()) {
- case 6600: mMode = VOAMRWB_MD66;
- break;
- case 8850: mMode = VOAMRWB_MD885;
- break;
- case 12650: mMode = VOAMRWB_MD1265;
- break;
- case 14250: mMode = VOAMRWB_MD1425;
- break;
- case 15850: mMode = VOAMRWB_MD1585;
- break;
- case 18250: mMode = VOAMRWB_MD1825;
- break;
- case 19850: mMode = VOAMRWB_MD1985;
- break;
- case 23050: mMode = VOAMRWB_MD2305;
- break;
- case 23850: mMode = VOAMRWB_MD2385;
- break;
- default: mMode = VOAMRWB_MD2305;
- }
- status_t err = initEncoder();
- mIsFirst = true;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mAnchorTimeStamp = 0;
- mProcessedSamples = 0;
- mFilledLen = 0;
-
- return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-void C2SoftAmrWbEnc::onRelease() {
- if (mEncoderHandle) {
- CHECK_EQ((VO_U32)VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
- mEncoderHandle = nullptr;
- }
- if (mApiHandle) {
- delete mApiHandle;
- mApiHandle = nullptr;
- }
- if (mMemOperator) {
- delete mMemOperator;
- mMemOperator = nullptr;
- }
-}
-
-c2_status_t C2SoftAmrWbEnc::onStop() {
- for (int i = 0; i < kNumSamplesPerFrame; i++) {
- mInputFrame[i] = 0x0008; /* EHF_MASK */
- }
- uint8_t outBuffer[kNumBytesPerInputFrame];
- (void) encodeInput(outBuffer, kNumBytesPerInputFrame);
- mIsFirst = true;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mAnchorTimeStamp = 0;
- mProcessedSamples = 0;
- mFilledLen = 0;
-
- return C2_OK;
-}
-
-void C2SoftAmrWbEnc::onReset() {
- (void) onStop();
-}
-
-c2_status_t C2SoftAmrWbEnc::onFlush_sm() {
- return onStop();
-}
-
-status_t C2SoftAmrWbEnc::initEncoder() {
- mApiHandle = new VO_AUDIO_CODECAPI;
- if (!mApiHandle) return NO_MEMORY;
-
- if (VO_ERR_NONE != voGetAMRWBEncAPI(mApiHandle)) {
- ALOGE("Failed to get api handle");
- return UNKNOWN_ERROR;
- }
-
- mMemOperator = new VO_MEM_OPERATOR;
- if (!mMemOperator) return NO_MEMORY;
-
- mMemOperator->Alloc = cmnMemAlloc;
- mMemOperator->Copy = cmnMemCopy;
- mMemOperator->Free = cmnMemFree;
- mMemOperator->Set = cmnMemSet;
- mMemOperator->Check = cmnMemCheck;
-
- VO_CODEC_INIT_USERDATA userData;
- memset(&userData, 0, sizeof(userData));
- userData.memflag = VO_IMF_USERMEMOPERATOR;
- userData.memData = (VO_PTR) mMemOperator;
-
- if (VO_ERR_NONE != mApiHandle->Init(
- &mEncoderHandle, VO_AUDIO_CodingAMRWB, &userData)) {
- ALOGE("Failed to init AMRWB encoder");
- return UNKNOWN_ERROR;
- }
-
- VOAMRWBFRAMETYPE type = VOAMRWB_RFC3267;
- if (VO_ERR_NONE != mApiHandle->SetParam(
- mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &type)) {
- ALOGE("Failed to set AMRWB encoder frame type to %d", type);
- return UNKNOWN_ERROR;
- }
-
- if (VO_ERR_NONE !=
- mApiHandle->SetParam(
- mEncoderHandle, VO_PID_AMRWB_MODE, &mMode)) {
- ALOGE("Failed to set AMRWB encoder mode to %d", mMode);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-int C2SoftAmrWbEnc::encodeInput(uint8_t *buffer, uint32_t length) {
- VO_CODECBUFFER inputData;
- memset(&inputData, 0, sizeof(inputData));
- inputData.Buffer = (unsigned char *) mInputFrame;
- inputData.Length = kNumBytesPerInputFrame;
-
- CHECK_EQ((VO_U32)VO_ERR_NONE,
- mApiHandle->SetInputData(mEncoderHandle, &inputData));
-
- VO_AUDIO_OUTPUTINFO outputInfo;
- memset(&outputInfo, 0, sizeof(outputInfo));
- VO_CODECBUFFER outputData;
- memset(&outputData, 0, sizeof(outputData));
- outputData.Buffer = buffer;
- outputData.Length = length;
- VO_U32 ret = mApiHandle->GetOutputData(
- mEncoderHandle, &outputData, &outputInfo);
- if (ret != VO_ERR_NONE && ret != VO_ERR_INPUT_BUFFER_SMALL) {
- ALOGD("encountered error during encode call");
- return -1;
- }
- return outputData.Length;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftAmrWbEnc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- size_t inOffset = 0u;
- size_t inSize = 0u;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
- size_t outCapacity = kNumBytesPerInputFrame;
- outCapacity += mFilledLen + inSize;
- std::shared_ptr<C2LinearBlock> outputBlock;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &outputBlock);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = outputBlock->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
- uint64_t outTimeStamp =
- mProcessedSamples * 1000000ll / mIntf->getSampleRate();
- size_t inPos = 0;
- size_t outPos = 0;
- while (inPos < inSize) {
- const uint8_t *inPtr = rView.data() + inOffset;
- int validSamples = mFilledLen / sizeof(int16_t);
- if ((inPos + (kNumBytesPerInputFrame - mFilledLen)) <= inSize) {
- memcpy(mInputFrame + validSamples, inPtr + inPos,
- (kNumBytesPerInputFrame - mFilledLen));
- inPos += (kNumBytesPerInputFrame - mFilledLen);
- } else {
- memcpy(mInputFrame + validSamples, inPtr + inPos, (inSize - inPos));
- mFilledLen += (inSize - inPos);
- inPos += (inSize - inPos);
- if (eos) {
- validSamples = mFilledLen / sizeof(int16_t);
- memset(mInputFrame + validSamples, 0, (kNumBytesPerInputFrame - mFilledLen));
- } else break;
- }
- int numEncBytes = encodeInput((wView.data() + outPos), outCapacity - outPos);
- if (numEncBytes < 0) {
- ALOGE("encodeFrame call failed, state [%d %zu %zu]", numEncBytes, outPos, outCapacity);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- outPos += numEncBytes;
- mProcessedSamples += kNumSamplesPerFrame;
- mFilledLen = 0;
- }
- ALOGV("causal sample size %d", mFilledLen);
- if (mIsFirst) {
- mIsFirst = false;
- mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
- }
- fillEmptyWork(work);
- if (outPos != 0) {
- work->worklets.front()->output.buffers.push_back(
- createLinearBuffer(std::move(outputBlock), 0, outPos));
- work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
- }
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- if (mFilledLen) ALOGV("Discarding trailing %d bytes", mFilledLen);
- }
-}
-
-c2_status_t C2SoftAmrWbEnc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- onFlush_sm();
- return C2_OK;
-}
-
-class C2SoftAmrWbEncFactory : public C2ComponentFactory {
-public:
- C2SoftAmrWbEncFactory()
- : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {}
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAmrWbEnc(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftAmrWbEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAmrWbEnc::IntfImpl>(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftAmrWbEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAmrWbEncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAmrWbEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/amr_nb_wb/C2SoftAmrWbEnc.h b/media/codecs/amr_nb_wb/C2SoftAmrWbEnc.h
deleted file mode 100644
index 0cc9e9f..0000000
--- a/media/codecs/amr_nb_wb/C2SoftAmrWbEnc.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AMR_WB_ENC_H_
-#define ANDROID_C2_SOFT_AMR_WB_ENC_H_
-
-#include <SimpleC2Component.h>
-
-#include "voAMRWB.h"
-
-namespace android {
-
-class C2SoftAmrWbEnc : public SimpleC2Component {
-public:
- class IntfImpl;
- C2SoftAmrWbEnc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftAmrWbEnc();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- std::shared_ptr<IntfImpl> mIntf;
- static const int32_t kNumSamplesPerFrame = 320;
- static const int32_t kNumBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
-
- void *mEncoderHandle;
- VO_AUDIO_CODECAPI *mApiHandle;
- VO_MEM_OPERATOR *mMemOperator;
- VOAMRWBMODE mMode;
- bool mIsFirst;
- bool mSignalledError;
- bool mSignalledOutputEos;
- uint64_t mAnchorTimeStamp;
- uint64_t mProcessedSamples;
- int32_t mFilledLen;
- int16_t mInputFrame[kNumSamplesPerFrame];
-
- status_t initEncoder();
- int encodeInput(uint8_t *buffer, uint32_t length);
-
- C2_DO_NOT_COPY(C2SoftAmrWbEnc);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AMR_WB_ENC_H_
diff --git a/media/codecs/amr_nb_wb/MODULE_LICENSE_APACHE2 b/media/codecs/amr_nb_wb/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/amr_nb_wb/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/amr_nb_wb/NOTICE b/media/codecs/amr_nb_wb/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/amr_nb_wb/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/amr_nb_wb/patent_disclaimer.txt b/media/codecs/amr_nb_wb/patent_disclaimer.txt
deleted file mode 100644
index b4bf11d..0000000
--- a/media/codecs/amr_nb_wb/patent_disclaimer.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-THIS IS NOT A GRANT OF PATENT RIGHTS.
-
-Google makes no representation or warranty that the codecs for which
-source code is made available hereunder are unencumbered by
-third-party patents. Those intending to use this source code in
-hardware or software products are advised that implementations of
-these codecs, including in open source software or shareware, may
-require patent licenses from the relevant patent holders.
diff --git a/media/codecs/avc/Android.bp b/media/codecs/avc/Android.bp
deleted file mode 100644
index d883951..0000000
--- a/media/codecs/avc/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2avcdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- static_libs: ["libavcdec"],
-
- srcs: ["C2SoftAvcDec.cpp"],
-
- include_dirs: [
- "external/libavc/decoder",
- "external/libavc/common",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2avcenc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- static_libs: ["libavcenc"],
-
- srcs: ["C2SoftAvcEnc.cpp"],
-
- include_dirs: [
- "external/libavc/encoder",
- "external/libavc/common",
- ],
-
- cflags: [
- "-Wno-unused-variable",
- ],
-}
diff --git a/media/codecs/avc/C2SoftAvcDec.cpp b/media/codecs/avc/C2SoftAvcDec.cpp
deleted file mode 100644
index 3e62744..0000000
--- a/media/codecs/avc/C2SoftAvcDec.cpp
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright 2017 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 "C2SoftAvcDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <Codec2Mapper.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftAvcDec.h"
-#include "ih264d.h"
-
-namespace android {
-
-namespace {
-
-constexpr char COMPONENT_NAME[] = "c2.android.avc.decoder";
-
-} // namespace
-
-class C2SoftAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : SimpleInterface<void>::BaseParams(
- helper,
- COMPONENT_NAME,
- C2Component::KIND_DECODER,
- C2Component::DOMAIN_VIDEO,
- MEDIA_MIMETYPE_VIDEO_AVC) {
- noPrivateBuffers(); // TODO: account for our buffers here
- noInputReferences();
- noOutputReferences();
- noInputLatency();
- noTimeStretch();
-
- // TODO: output latency and reordering
-
- addParameter(
- DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
- .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
- .build());
-
- // coded and output picture size is the same for this codec
- addParameter(
- DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 4080, 2),
- C2F(mSize, height).inRange(2, 4080, 2),
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
- .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 4080, 2),
- C2F(mSize, height).inRange(2, 4080, 2),
- })
- .withSetter(MaxPictureSizeSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_AVC_CONSTRAINED_BASELINE, C2Config::LEVEL_AVC_5_2))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_AVC_CONSTRAINED_BASELINE,
- C2Config::PROFILE_AVC_BASELINE,
- C2Config::PROFILE_AVC_MAIN,
- C2Config::PROFILE_AVC_CONSTRAINED_HIGH,
- C2Config::PROFILE_AVC_PROGRESSIVE_HIGH,
- C2Config::PROFILE_AVC_HIGH}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_AVC_1, C2Config::LEVEL_AVC_1B, C2Config::LEVEL_AVC_1_1,
- C2Config::LEVEL_AVC_1_2, C2Config::LEVEL_AVC_1_3,
- C2Config::LEVEL_AVC_2, C2Config::LEVEL_AVC_2_1, C2Config::LEVEL_AVC_2_2,
- C2Config::LEVEL_AVC_3, C2Config::LEVEL_AVC_3_1, C2Config::LEVEL_AVC_3_2,
- C2Config::LEVEL_AVC_4, C2Config::LEVEL_AVC_4_1, C2Config::LEVEL_AVC_4_2,
- C2Config::LEVEL_AVC_5, C2Config::LEVEL_AVC_5_1, C2Config::LEVEL_AVC_5_2
- })
- })
- .withSetter(ProfileLevelSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
- .withFields({
- C2F(mMaxInputSize, value).any(),
- })
- .calculatedAs(MaxInputSizeSetter, mMaxSize)
- .build());
-
- C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
- std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- 1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
- memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
-
- defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- { C2ChromaOffsetStruct::ITU_YUV_420_0() },
- 0u, 8u /* bitDepth */, C2Color::YUV_420);
- helper->addStructDescriptors<C2ChromaOffsetStruct>();
-
- addParameter(
- DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
- .withConstValue(defaultColorInfo)
- .build());
-
- addParameter(
- DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsTuning::output(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mDefaultColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mDefaultColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mDefaultColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mDefaultColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(DefaultColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::input(
- 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mCodedColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mCodedColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mCodedColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mCodedColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(CodedColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::output(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
- .build());
-
- // TODO: support more formats?
- addParameter(
- DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
- .build());
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
- C2P<C2VideoSizeStreamInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- // TODO: get max width/height from the size's field helpers vs. hardcoding
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4080u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4080u);
- return C2R::Ok();
- }
-
- static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
- const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
- (void)mayBlock;
- // assume compression ratio of 2
- me.set().value = (((maxSize.v.width + 15) / 16) * ((maxSize.v.height + 15) / 16) * 192);
- return C2R::Ok();
- }
-
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- (void)size;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
- }
-
- static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
- }
-
- static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
- const C2P<C2StreamColorAspectsTuning::output> &def,
- const C2P<C2StreamColorAspectsInfo::input> &coded) {
- (void)mayBlock;
- // take default values for all unspecified fields, and coded values for specified ones
- me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
- me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
- ? def.v.primaries : coded.v.primaries;
- me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
- ? def.v.transfer : coded.v.transfer;
- me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
- return C2R::Ok();
- }
-
- std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
- return mColorAspects;
- }
-
-private:
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
- std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
- std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
- std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
- std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
- std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
- std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
-};
-
-static size_t getCpuCoreCount() {
- long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
- cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- // _SC_NPROC_ONLN must be defined...
- cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
- CHECK(cpuCoreCount >= 1);
- ALOGV("Number of CPU cores: %ld", cpuCoreCount);
- return (size_t)cpuCoreCount;
-}
-
-static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
- (void) ctxt;
- return memalign(alignment, size);
-}
-
-static void ivd_aligned_free(void *ctxt, void *mem) {
- (void) ctxt;
- free(mem);
-}
-
-C2SoftAvcDec::C2SoftAvcDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mDecHandle(nullptr),
- mOutBufferFlush(nullptr),
- mIvColorFormat(IV_YUV_420P),
- mWidth(320),
- mHeight(240),
- mHeaderDecoded(false) {
- GENERATE_FILE_NAMES();
- CREATE_DUMP_FILE(mInFile);
-}
-
-C2SoftAvcDec::~C2SoftAvcDec() {
- onRelease();
-}
-
-c2_status_t C2SoftAvcDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftAvcDec::onStop() {
- if (OK != resetDecoder()) return C2_CORRUPTED;
- resetPlugin();
- return C2_OK;
-}
-
-void C2SoftAvcDec::onReset() {
- (void) onStop();
-}
-
-void C2SoftAvcDec::onRelease() {
- (void) deleteDecoder();
- if (mOutBufferFlush) {
- ivd_aligned_free(nullptr, mOutBufferFlush);
- mOutBufferFlush = nullptr;
- }
- if (mOutBlock) {
- mOutBlock.reset();
- }
-}
-
-c2_status_t C2SoftAvcDec::onFlush_sm() {
- if (OK != setFlushMode()) return C2_CORRUPTED;
-
- uint32_t bufferSize = mStride * mHeight * 3 / 2;
- mOutBufferFlush = (uint8_t *)ivd_aligned_malloc(nullptr, 128, bufferSize);
- if (!mOutBufferFlush) {
- ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
- return C2_NO_MEMORY;
- }
-
- while (true) {
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
-
- setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- if (0 == s_decode_op.u4_output_present) {
- resetPlugin();
- break;
- }
- }
-
- if (mOutBufferFlush) {
- ivd_aligned_free(nullptr, mOutBufferFlush);
- mOutBufferFlush = nullptr;
- }
-
- return C2_OK;
-}
-
-status_t C2SoftAvcDec::createDecoder() {
- ivdext_create_ip_t s_create_ip;
- ivdext_create_op_t s_create_op;
-
- s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
- s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
- s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
- s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat;
- s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
- s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
- s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
- s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(nullptr,
- &s_create_ip,
- &s_create_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__,
- s_create_op.s_ivd_create_op_t.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mDecHandle = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
- mDecHandle->pv_fxns = (void *)ivdec_api_function;
- mDecHandle->u4_size = sizeof(iv_obj_t);
-
- return OK;
-}
-
-status_t C2SoftAvcDec::setNumCores() {
- ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
- ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
-
- s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
- s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
- s_set_num_cores_ip.u4_num_cores = mNumCores;
- s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_num_cores_ip,
- &s_set_num_cores_op);
- if (IV_SUCCESS != status) {
- ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftAvcDec::setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode) {
- ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
- ivd_ctl_set_config_op_t s_set_dyn_params_op;
-
- s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
- s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
- s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
- s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
- s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
- s_set_dyn_params_ip.e_vid_dec_mode = dec_mode;
- s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_dyn_params_ip,
- &s_set_dyn_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-void C2SoftAvcDec::getVersion() {
- ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
- ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
- UWORD8 au1_buf[512];
-
- s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
- s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
- s_get_versioninfo_ip.pv_version_buffer = au1_buf;
- s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
- s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_get_versioninfo_ip,
- &s_get_versioninfo_op);
- if (status != IV_SUCCESS) {
- ALOGD("error in %s: 0x%x", __func__,
- s_get_versioninfo_op.u4_error_code);
- } else {
- ALOGV("ittiam decoder version number: %s",
- (char *) s_get_versioninfo_ip.pv_version_buffer);
- }
-}
-
-status_t C2SoftAvcDec::initDecoder() {
- if (OK != createDecoder()) return UNKNOWN_ERROR;
- mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN64(mWidth);
- mSignalledError = false;
- resetPlugin();
- (void) setNumCores();
- if (OK != setParams(mStride, IVD_DECODE_FRAME)) return UNKNOWN_ERROR;
- (void) getVersion();
-
- return OK;
-}
-
-bool C2SoftAvcDec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
- ivd_video_decode_op_t *ps_decode_op,
- C2ReadView *inBuffer,
- C2GraphicView *outBuffer,
- size_t inOffset,
- size_t inSize,
- uint32_t tsMarker) {
- uint32_t displayStride = mStride;
- uint32_t displayHeight = mHeight;
- size_t lumaSize = displayStride * displayHeight;
- size_t chromaSize = lumaSize >> 2;
-
- ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
- ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
- if (inBuffer) {
- ps_decode_ip->u4_ts = tsMarker;
- ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
- ps_decode_ip->u4_num_Bytes = inSize;
- } else {
- ps_decode_ip->u4_ts = 0;
- ps_decode_ip->pv_stream_buffer = nullptr;
- ps_decode_ip->u4_num_Bytes = 0;
- }
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
- if (outBuffer) {
- if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
- ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
- outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
- return false;
- }
- ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
- ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
- ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
- } else {
- ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferFlush;
- ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferFlush + lumaSize;
- ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferFlush + lumaSize + chromaSize;
- }
- ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
- ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
-
- return true;
-}
-
-bool C2SoftAvcDec::getVuiParams() {
- ivdext_ctl_get_vui_params_ip_t s_get_vui_params_ip;
- ivdext_ctl_get_vui_params_op_t s_get_vui_params_op;
-
- s_get_vui_params_ip.u4_size = sizeof(ivdext_ctl_get_vui_params_ip_t);
- s_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_get_vui_params_ip.e_sub_cmd =
- (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_VUI_PARAMS;
- s_get_vui_params_op.u4_size = sizeof(ivdext_ctl_get_vui_params_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_get_vui_params_ip,
- &s_get_vui_params_op);
- if (status != IV_SUCCESS) {
- ALOGD("error in %s: 0x%x", __func__, s_get_vui_params_op.u4_error_code);
- return false;
- }
-
- VuiColorAspects vuiColorAspects;
- vuiColorAspects.primaries = s_get_vui_params_op.u1_colour_primaries;
- vuiColorAspects.transfer = s_get_vui_params_op.u1_tfr_chars;
- vuiColorAspects.coeffs = s_get_vui_params_op.u1_matrix_coeffs;
- vuiColorAspects.fullRange = s_get_vui_params_op.u1_video_full_range_flag;
-
- // convert vui aspects to C2 values if changed
- if (!(vuiColorAspects == mBitstreamColorAspects)) {
- mBitstreamColorAspects = vuiColorAspects;
- ColorAspects sfAspects;
- C2StreamColorAspectsInfo::input codedAspects = { 0u };
- ColorUtils::convertIsoColorAspectsToCodecAspects(
- vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
- vuiColorAspects.fullRange, sfAspects);
- if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
- codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
- codedAspects.range = C2Color::RANGE_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
- codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
- codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
- }
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
- }
- return true;
-}
-
-status_t C2SoftAvcDec::setFlushMode() {
- ivd_ctl_flush_ip_t s_set_flush_ip;
- ivd_ctl_flush_op_t s_set_flush_op;
-
- s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
- s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
- s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_flush_ip,
- &s_set_flush_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftAvcDec::resetDecoder() {
- ivd_ctl_reset_ip_t s_reset_ip;
- ivd_ctl_reset_op_t s_reset_op;
-
- s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
- s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
- s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_reset_ip,
- &s_reset_op);
- if (IV_SUCCESS != status) {
- ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mStride = 0;
- (void) setNumCores();
- mSignalledError = false;
- mHeaderDecoded = false;
-
- return OK;
-}
-
-void C2SoftAvcDec::resetPlugin() {
- mSignalledOutputEos = false;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
-}
-
-status_t C2SoftAvcDec::deleteDecoder() {
- if (mDecHandle) {
- ivdext_delete_ip_t s_delete_ip;
- ivdext_delete_op_t s_delete_op;
-
- s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
- s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
- s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_delete_ip,
- &s_delete_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__,
- s_delete_op.s_ivd_delete_op_t.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mDecHandle = nullptr;
- }
-
- return OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftAvcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
- std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
- C2Rect(mWidth, mHeight));
- mOutBlock = nullptr;
- {
- IntfImpl::Lock lock = mIntf->lock();
- buffer->setInfo(mIntf->getColorAspects_l());
- }
-
- auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
- fillWork(work);
- } else {
- finish(index, fillWork);
- }
-}
-
-c2_status_t C2SoftAvcDec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
- if (!mDecHandle) {
- ALOGE("not supposed to be here, invalid decoder context");
- return C2_CORRUPTED;
- }
- if (mStride != ALIGN64(mWidth)) {
- mStride = ALIGN64(mWidth);
- if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
- }
- if (mOutBlock &&
- (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
- mOutBlock.reset();
- }
- if (!mOutBlock) {
- uint32_t format = HAL_PIXEL_FORMAT_YV12;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return err;
- }
- ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
- }
-
- return C2_OK;
-}
-
-// TODO: can overall error checking be improved?
-// TODO: allow configuration of color format and usage for graphic buffers instead
-// of hard coding them to HAL_PIXEL_FORMAT_YV12
-// TODO: pass coloraspects information to surface
-// TODO: test support for dynamic change in resolution
-// TODO: verify if the decoder sent back all frames
-void C2SoftAvcDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 0u;
- work->worklets.front()->output.flags = work->input.flags;
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- size_t inOffset = 0u;
- size_t inSize = 0u;
- uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- bool hasPicture = false;
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
- size_t inPos = 0;
- while (inPos < inSize) {
- if (C2_OK != ensureDecoderState(pool)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
-
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
- {
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
- if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
- inOffset + inPos, inSize - inPos, workIndex)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
-
- if (false == mHeaderDecoded) {
- /* Decode header and get dimensions */
- setParams(mStride, IVD_DECODE_HEADER);
- }
-
- WORD32 delay;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- WORD32 decodeTime;
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
- s_decode_op.u4_num_bytes_consumed);
- }
- if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGE("allocation failure in decoder");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGV("resolution changed");
- drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
- resetDecoder();
- resetPlugin();
- work->workletsProcessed = 0u;
-
- /* Decode header and get new dimensions */
- setParams(mStride, IVD_DECODE_HEADER);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- }
- if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
- if (mHeaderDecoded == false) {
- mHeaderDecoded = true;
- setParams(ALIGN64(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
- }
- if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
- mWidth = s_decode_op.u4_pic_wd;
- mHeight = s_decode_op.u4_pic_ht;
- CHECK_EQ(0u, s_decode_op.u4_output_present);
-
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- } else {
- ALOGE("Cannot set width and height");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- continue;
- }
- }
- (void)getVuiParams();
- hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
- if (s_decode_op.u4_output_present) {
- finishWork(s_decode_op.u4_ts, work);
- }
- if (0 == s_decode_op.u4_num_bytes_consumed) {
- ALOGD("Bytes consumed is zero. Ignoring remaining bytes");
- break;
- }
- inPos += s_decode_op.u4_num_bytes_consumed;
- if (hasPicture && (inSize - inPos)) {
- ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
- (int)inSize - (int)inPos);
- break;
- }
- }
- if (eos) {
- drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
- mSignalledOutputEos = true;
- } else if (!hasPicture) {
- fillEmptyWork(work);
- }
-}
-
-c2_status_t C2SoftAvcDec::drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work) {
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- if (OK != setFlushMode()) return C2_CORRUPTED;
- while (true) {
- if (C2_OK != ensureDecoderState(pool)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return C2_CORRUPTED;
- }
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- return C2_CORRUPTED;
- }
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
- if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- return C2_CORRUPTED;
- }
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- if (s_decode_op.u4_output_present) {
- finishWork(s_decode_op.u4_ts, work);
- } else {
- fillEmptyWork(work);
- break;
- }
- }
-
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftAvcDecFactory : public C2ComponentFactory {
-public:
- C2SoftAvcDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAvcDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftAvcDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAvcDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftAvcDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAvcDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAvcDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/avc/C2SoftAvcDec.h b/media/codecs/avc/C2SoftAvcDec.h
deleted file mode 100644
index 2127a93..0000000
--- a/media/codecs/avc/C2SoftAvcDec.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AVC_DEC_H_
-#define ANDROID_C2_SOFT_AVC_DEC_H_
-
-#include <sys/time.h>
-
-#include <media/stagefright/foundation/ColorUtils.h>
-
-#include <SimpleC2Component.h>
-
-#include "ih264_typedefs.h"
-#include "iv.h"
-#include "ivd.h"
-
-namespace android {
-
-#define ivdec_api_function ih264d_api_function
-#define ivdext_create_ip_t ih264d_create_ip_t
-#define ivdext_create_op_t ih264d_create_op_t
-#define ivdext_delete_ip_t ih264d_delete_ip_t
-#define ivdext_delete_op_t ih264d_delete_op_t
-#define ivdext_ctl_set_num_cores_ip_t ih264d_ctl_set_num_cores_ip_t
-#define ivdext_ctl_set_num_cores_op_t ih264d_ctl_set_num_cores_op_t
-#define ivdext_ctl_get_vui_params_ip_t ih264d_ctl_get_vui_params_ip_t
-#define ivdext_ctl_get_vui_params_op_t ih264d_ctl_get_vui_params_op_t
-#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
-#define MAX_NUM_CORES 4
-#define IVDEXT_CMD_CTL_SET_NUM_CORES \
- (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
-#ifdef FILE_DUMP_ENABLE
- #define INPUT_DUMP_PATH "/sdcard/clips/avcd_input"
- #define INPUT_DUMP_EXT "h264"
- #define GENERATE_FILE_NAMES() { \
- GETTIME(&mTimeStart, NULL); \
- strcpy(mInFile, ""); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
- INPUT_DUMP_EXT); \
- }
- #define CREATE_DUMP_FILE(m_filename) { \
- FILE *fp = fopen(m_filename, "wb"); \
- if (fp != NULL) { \
- fclose(fp); \
- } else { \
- ALOGD("Could not open file %s", m_filename); \
- } \
- }
- #define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)\
- { \
- FILE *fp = fopen(m_filename, "ab"); \
- if (fp != NULL && m_buf != NULL && m_offset == 0) { \
- int i; \
- i = fwrite(m_buf, 1, m_size, fp); \
- ALOGD("fwrite ret %d to write %d", i, m_size); \
- if (i != (int) m_size) { \
- ALOGD("Error in fwrite, returned %d", i); \
- perror("Error in write to file"); \
- } \
- } else if (fp == NULL) { \
- ALOGD("Could not write to file %s", m_filename);\
- } \
- if (fp) { \
- fclose(fp); \
- } \
- }
-#else /* FILE_DUMP_ENABLE */
- #define INPUT_DUMP_PATH
- #define INPUT_DUMP_EXT
- #define OUTPUT_DUMP_PATH
- #define OUTPUT_DUMP_EXT
- #define GENERATE_FILE_NAMES()
- #define CREATE_DUMP_FILE(m_filename)
- #define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)
-#endif /* FILE_DUMP_ENABLE */
-
-
-class C2SoftAvcDec : public SimpleC2Component {
-public:
- class IntfImpl;
- C2SoftAvcDec(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftAvcDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- status_t createDecoder();
- status_t setNumCores();
- status_t setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode);
- void getVersion();
- status_t initDecoder();
- bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
- ivd_video_decode_op_t *ps_decode_op,
- C2ReadView *inBuffer,
- C2GraphicView *outBuffer,
- size_t inOffset,
- size_t inSize,
- uint32_t tsMarker);
- bool getVuiParams();
- c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
- void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
- status_t setFlushMode();
- c2_status_t drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work);
- status_t resetDecoder();
- void resetPlugin();
- status_t deleteDecoder();
-
- std::shared_ptr<IntfImpl> mIntf;
-
- // TODO:This is not the right place for this enum. These should
- // be part of c2-vndk so that they can be accessed by all video plugins
- // until then, make them feel at home
- enum {
- kNotSupported,
- kPreferBitstream,
- kPreferContainer,
- };
-
- iv_obj_t *mDecHandle;
- std::shared_ptr<C2GraphicBlock> mOutBlock;
- uint8_t *mOutBufferFlush;
-
- size_t mNumCores;
- IV_COLOR_FORMAT_T mIvColorFormat;
-
- uint32_t mWidth;
- uint32_t mHeight;
- uint32_t mStride;
- bool mSignalledOutputEos;
- bool mSignalledError;
- bool mHeaderDecoded;
- // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
- // converting them to C2 values for each frame
- struct VuiColorAspects {
- uint8_t primaries;
- uint8_t transfer;
- uint8_t coeffs;
- uint8_t fullRange;
-
- // default color aspects
- VuiColorAspects()
- : primaries(2), transfer(2), coeffs(2), fullRange(0) { }
-
- bool operator==(const VuiColorAspects &o) {
- return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
- && fullRange == o.fullRange;
- }
- } mBitstreamColorAspects;
-
- // profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
-#ifdef FILE_DUMP_ENABLE
- char mInFile[200];
-#endif /* FILE_DUMP_ENABLE */
-
- C2_DO_NOT_COPY(C2SoftAvcDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AVC_DEC_H_
diff --git a/media/codecs/avc/C2SoftAvcEnc.cpp b/media/codecs/avc/C2SoftAvcEnc.cpp
deleted file mode 100644
index bfe745c..0000000
--- a/media/codecs/avc/C2SoftAvcEnc.cpp
+++ /dev/null
@@ -1,1559 +0,0 @@
-/*
- * 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 "C2SoftAvcEnc"
-#include <log/log.h>
-#include <utils/misc.h>
-
-#include <media/hardware/VideoAPI.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/foundation/AUtils.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <Codec2BufferUtils.h>
-#include <SimpleC2Interface.h>
-#include <util/C2InterfaceHelper.h>
-
-#include "C2SoftAvcEnc.h"
-#include "ih264e.h"
-#include "ih264e_error.h"
-
-namespace android {
-
-class C2SoftAvcEnc::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatVideo))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_VIDEO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_VIDEO_AVC))
- .build());
-
- addParameter(
- DefineParam(mUsage, C2_NAME_INPUT_STREAM_USAGE_SETTING)
- .withConstValue(new C2StreamUsageTuning::input(
- 0u, (uint64_t)C2MemoryUsage::CPU_READ))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_NAME_STREAM_VIDEO_SIZE_SETTING)
- .withDefault(new C2VideoSizeStreamTuning::input(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 2560, 2),
- C2F(mSize, height).inRange(2, 2560, 2),
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mFrameRate, C2_NAME_STREAM_FRAME_RATE_SETTING)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
- // TODO: More restriction?
- .withFields({C2F(mFrameRate, value).greaterThan(0.)})
- .withSetter(Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
- .withSetter(BitrateSetter)
- .build());
-
- addParameter(
- DefineParam(mIntraRefresh, C2_PARAMKEY_INTRA_REFRESH)
- .withDefault(new C2StreamIntraRefreshTuning::output(
- 0u, C2Config::INTRA_REFRESH_DISABLED, 0.))
- .withFields({
- C2F(mIntraRefresh, mode).oneOf({
- C2Config::INTRA_REFRESH_DISABLED, C2Config::INTRA_REFRESH_ARBITRARY }),
- C2F(mIntraRefresh, period).any()
- })
- .withSetter(IntraRefreshSetter)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::output(
- 0u, PROFILE_AVC_CONSTRAINED_BASELINE, LEVEL_AVC_4_1))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- PROFILE_AVC_BASELINE,
- PROFILE_AVC_CONSTRAINED_BASELINE,
- PROFILE_AVC_MAIN,
- }),
- C2F(mProfileLevel, level).oneOf({
- LEVEL_AVC_1,
- LEVEL_AVC_1B,
- LEVEL_AVC_1_1,
- LEVEL_AVC_1_2,
- LEVEL_AVC_1_3,
- LEVEL_AVC_2,
- LEVEL_AVC_2_1,
- LEVEL_AVC_2_2,
- LEVEL_AVC_3,
- LEVEL_AVC_3_1,
- LEVEL_AVC_3_2,
- LEVEL_AVC_4,
- LEVEL_AVC_4_1,
- LEVEL_AVC_4_2,
- LEVEL_AVC_5,
- }),
- })
- .withSetter(ProfileLevelSetter, mSize, mFrameRate, mBitrate)
- .build());
-
- addParameter(
- DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
- .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
- .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
- .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
- .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
- .withFields({C2F(mSyncFramePeriod, value).any()})
- .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
- .build());
- }
-
- static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.value <= 4096) {
- me.set().value = 4096;
- }
- return res;
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
- C2P<C2StreamPictureSizeInfo::input> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R ProfileLevelSetter(
- bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output> &me,
- const C2P<C2VideoSizeStreamTuning::input> &size,
- const C2P<C2StreamFrameRateInfo::output> &frameRate,
- const C2P<C2BitrateTuning::output> &bitrate) {
- (void)mayBlock;
- if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
- me.set().profile = PROFILE_AVC_CONSTRAINED_BASELINE;
- }
-
- struct LevelLimits {
- C2Config::level_t level;
- float mbsPerSec;
- uint64_t mbs;
- uint32_t bitrate;
- };
- constexpr LevelLimits kLimits[] = {
- { LEVEL_AVC_1, 1485, 99, 64000 },
- // Decoder does not properly handle level 1b.
- // { LEVEL_AVC_1B, 1485, 99, 128000 },
- { LEVEL_AVC_1_1, 3000, 396, 192000 },
- { LEVEL_AVC_1_2, 6000, 396, 384000 },
- { LEVEL_AVC_1_3, 11880, 396, 768000 },
- { LEVEL_AVC_2, 11880, 396, 2000000 },
- { LEVEL_AVC_2_1, 19800, 792, 4000000 },
- { LEVEL_AVC_2_2, 20250, 1620, 4000000 },
- { LEVEL_AVC_3, 40500, 1620, 10000000 },
- { LEVEL_AVC_3_1, 108000, 3600, 14000000 },
- { LEVEL_AVC_3_2, 216000, 5120, 20000000 },
- { LEVEL_AVC_4, 245760, 8192, 20000000 },
- { LEVEL_AVC_4_1, 245760, 8192, 50000000 },
- { LEVEL_AVC_4_2, 522240, 8704, 50000000 },
- { LEVEL_AVC_5, 589824, 22080, 135000000 },
- };
-
- uint64_t mbs = uint64_t((size.v.width + 15) / 16) * ((size.v.height + 15) / 16);
- float mbsPerSec = float(mbs) * frameRate.v.value;
-
- // Check if the supplied level meets the MB / bitrate requirements. If
- // not, update the level with the lowest level meeting the requirements.
-
- bool found = false;
- // By default needsUpdate = false in case the supplied level does meet
- // the requirements. For Level 1b, we want to update the level anyway,
- // so we set it to true in that case.
- bool needsUpdate = (me.v.level == LEVEL_AVC_1B);
- for (const LevelLimits &limit : kLimits) {
- if (mbs <= limit.mbs && mbsPerSec <= limit.mbsPerSec &&
- bitrate.v.value <= limit.bitrate) {
- // This is the lowest level that meets the requirements, and if
- // we haven't seen the supplied level yet, that means we don't
- // need the update.
- if (needsUpdate) {
- ALOGD("Given level %x does not cover current configuration: "
- "adjusting to %x", me.v.level, limit.level);
- me.set().level = limit.level;
- }
- found = true;
- break;
- }
- if (me.v.level == limit.level) {
- // We break out of the loop when the lowest feasible level is
- // found. The fact that we're here means that our level doesn't
- // meet the requirement and needs to be updated.
- needsUpdate = true;
- }
- }
- if (!found) {
- // We set to the highest supported level.
- me.set().level = LEVEL_AVC_5;
- }
-
- return C2R::Ok();
- }
-
- static C2R IntraRefreshSetter(bool mayBlock, C2P<C2StreamIntraRefreshTuning::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.period < 1) {
- me.set().mode = C2Config::INTRA_REFRESH_DISABLED;
- me.set().period = 0;
- } else {
- // only support arbitrary mode (cyclic in our case)
- me.set().mode = C2Config::INTRA_REFRESH_ARBITRARY;
- }
- return res;
- }
-
- IV_PROFILE_T getProfile_l() const {
- switch (mProfileLevel->profile) {
- case PROFILE_AVC_CONSTRAINED_BASELINE: [[fallthrough]];
- case PROFILE_AVC_BASELINE: return IV_PROFILE_BASE;
- case PROFILE_AVC_MAIN: return IV_PROFILE_MAIN;
- default:
- ALOGD("Unrecognized profile: %x", mProfileLevel->profile);
- return IV_PROFILE_DEFAULT;
- }
- }
-
- UWORD32 getLevel_l() const {
- struct Level {
- C2Config::level_t c2Level;
- UWORD32 avcLevel;
- };
- constexpr Level levels[] = {
- { LEVEL_AVC_1, 10 },
- { LEVEL_AVC_1B, 9 },
- { LEVEL_AVC_1_1, 11 },
- { LEVEL_AVC_1_2, 12 },
- { LEVEL_AVC_1_3, 13 },
- { LEVEL_AVC_2, 20 },
- { LEVEL_AVC_2_1, 21 },
- { LEVEL_AVC_2_2, 22 },
- { LEVEL_AVC_3, 30 },
- { LEVEL_AVC_3_1, 31 },
- { LEVEL_AVC_3_2, 32 },
- { LEVEL_AVC_4, 40 },
- { LEVEL_AVC_4_1, 41 },
- { LEVEL_AVC_4_2, 42 },
- { LEVEL_AVC_5, 50 },
- };
- for (const Level &level : levels) {
- if (mProfileLevel->level == level.c2Level) {
- return level.avcLevel;
- }
- }
- ALOGD("Unrecognized level: %x", mProfileLevel->level);
- return 41;
- }
- uint32_t getSyncFramePeriod_l() const {
- if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
- return 0;
- }
- double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
- return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
- }
-
- // unsafe getters
- std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
- std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
- std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
- std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamUsageTuning::input> mUsage;
- std::shared_ptr<C2VideoSizeStreamTuning::input> mSize;
- std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
- std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
- std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
-};
-
-#define ive_api_function ih264e_api_function
-
-constexpr char COMPONENT_NAME[] = "c2.android.avc.encoder";
-
-namespace {
-
-// From external/libavc/encoder/ih264e_bitstream.h
-constexpr uint32_t MIN_STREAM_SIZE = 0x800;
-
-static size_t GetCPUCoreCount() {
- long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
- cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- // _SC_NPROC_ONLN must be defined...
- cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
- CHECK(cpuCoreCount >= 1);
- ALOGV("Number of CPU cores: %ld", cpuCoreCount);
- return (size_t)cpuCoreCount;
-}
-
-} // namespace
-
-C2SoftAvcEnc::C2SoftAvcEnc(
- const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mIvVideoColorFormat(IV_YUV_420P),
- mAVCEncProfile(IV_PROFILE_BASE),
- mAVCEncLevel(41),
- mStarted(false),
- mSawInputEOS(false),
- mSawOutputEOS(false),
- mSignalledError(false),
- mCodecCtx(nullptr),
- // TODO: output buffer size
- mOutBufferSize(524288) {
-
- // If dump is enabled, then open create an empty file
- GENERATE_FILE_NAMES();
- CREATE_DUMP_FILE(mInFile);
- CREATE_DUMP_FILE(mOutFile);
-
- initEncParams();
-}
-
-C2SoftAvcEnc::~C2SoftAvcEnc() {
- releaseEncoder();
-}
-
-c2_status_t C2SoftAvcEnc::onInit() {
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::onStop() {
- return C2_OK;
-}
-
-void C2SoftAvcEnc::onReset() {
- // TODO: use IVE_CMD_CTL_RESET?
- releaseEncoder();
- initEncParams();
-}
-
-void C2SoftAvcEnc::onRelease() {
- releaseEncoder();
-}
-
-c2_status_t C2SoftAvcEnc::onFlush_sm() {
- // TODO: use IVE_CMD_CTL_FLUSH?
- return C2_OK;
-}
-
-void C2SoftAvcEnc::initEncParams() {
- mCodecCtx = nullptr;
- mMemRecords = nullptr;
- mNumMemRecords = DEFAULT_MEM_REC_CNT;
- mHeaderGenerated = 0;
- mNumCores = GetCPUCoreCount();
- mArch = DEFAULT_ARCH;
- mSliceMode = DEFAULT_SLICE_MODE;
- mSliceParam = DEFAULT_SLICE_PARAM;
- mHalfPelEnable = DEFAULT_HPEL;
- mIInterval = DEFAULT_I_INTERVAL;
- mIDRInterval = DEFAULT_IDR_INTERVAL;
- mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL;
- mEnableFastSad = DEFAULT_ENABLE_FAST_SAD;
- mEnableAltRef = DEFAULT_ENABLE_ALT_REF;
- mEncSpeed = DEFAULT_ENC_SPEED;
- mIntra4x4 = DEFAULT_INTRA4x4;
- mConstrainedIntraFlag = DEFAULT_CONSTRAINED_INTRA;
- mPSNREnable = DEFAULT_PSNR_ENABLE;
- mReconEnable = DEFAULT_RECON_ENABLE;
- mEntropyMode = DEFAULT_ENTROPY_MODE;
- mBframes = DEFAULT_B_FRAMES;
-
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
-}
-
-c2_status_t C2SoftAvcEnc::setDimensions() {
- ive_ctl_set_dimensions_ip_t s_dimensions_ip;
- ive_ctl_set_dimensions_op_t s_dimensions_op;
- IV_STATUS_T status;
-
- s_dimensions_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_dimensions_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
- s_dimensions_ip.u4_ht = mSize->height;
- s_dimensions_ip.u4_wd = mSize->width;
-
- s_dimensions_ip.u4_timestamp_high = -1;
- s_dimensions_ip.u4_timestamp_low = -1;
-
- s_dimensions_ip.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
- s_dimensions_op.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
-
- status = ive_api_function(mCodecCtx, &s_dimensions_ip, &s_dimensions_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set frame dimensions = 0x%x\n",
- s_dimensions_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setNumCores() {
- IV_STATUS_T status;
- ive_ctl_set_num_cores_ip_t s_num_cores_ip;
- ive_ctl_set_num_cores_op_t s_num_cores_op;
- s_num_cores_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_num_cores_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
- s_num_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_CORES);
- s_num_cores_ip.u4_timestamp_high = -1;
- s_num_cores_ip.u4_timestamp_low = -1;
- s_num_cores_ip.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
-
- s_num_cores_op.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
-
- status = ive_api_function(
- mCodecCtx, (void *) &s_num_cores_ip, (void *) &s_num_cores_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set processor params = 0x%x\n",
- s_num_cores_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setFrameRate() {
- ive_ctl_set_frame_rate_ip_t s_frame_rate_ip;
- ive_ctl_set_frame_rate_op_t s_frame_rate_op;
- IV_STATUS_T status;
-
- s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
-
- s_frame_rate_ip.u4_src_frame_rate = mFrameRate->value + 0.5;
- s_frame_rate_ip.u4_tgt_frame_rate = mFrameRate->value + 0.5;
-
- s_frame_rate_ip.u4_timestamp_high = -1;
- s_frame_rate_ip.u4_timestamp_low = -1;
-
- s_frame_rate_ip.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
- s_frame_rate_op.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
-
- status = ive_api_function(mCodecCtx, &s_frame_rate_ip, &s_frame_rate_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set frame rate = 0x%x\n",
- s_frame_rate_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setIpeParams() {
- ive_ctl_set_ipe_params_ip_t s_ipe_params_ip;
- ive_ctl_set_ipe_params_op_t s_ipe_params_op;
- IV_STATUS_T status;
-
- s_ipe_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_ipe_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
-
- s_ipe_params_ip.u4_enable_intra_4x4 = mIntra4x4;
- s_ipe_params_ip.u4_enc_speed_preset = mEncSpeed;
- s_ipe_params_ip.u4_constrained_intra_pred = mConstrainedIntraFlag;
-
- s_ipe_params_ip.u4_timestamp_high = -1;
- s_ipe_params_ip.u4_timestamp_low = -1;
-
- s_ipe_params_ip.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
- s_ipe_params_op.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
-
- status = ive_api_function(mCodecCtx, &s_ipe_params_ip, &s_ipe_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set ipe params = 0x%x\n",
- s_ipe_params_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setBitRate() {
- ive_ctl_set_bitrate_ip_t s_bitrate_ip;
- ive_ctl_set_bitrate_op_t s_bitrate_op;
- IV_STATUS_T status;
-
- s_bitrate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_bitrate_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
-
- s_bitrate_ip.u4_target_bitrate = mBitrate->value;
-
- s_bitrate_ip.u4_timestamp_high = -1;
- s_bitrate_ip.u4_timestamp_low = -1;
-
- s_bitrate_ip.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
- s_bitrate_op.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
-
- status = ive_api_function(mCodecCtx, &s_bitrate_ip, &s_bitrate_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set bit rate = 0x%x\n", s_bitrate_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) {
- ive_ctl_set_frame_type_ip_t s_frame_type_ip;
- ive_ctl_set_frame_type_op_t s_frame_type_op;
- IV_STATUS_T status;
- s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
-
- s_frame_type_ip.e_frame_type = e_frame_type;
-
- s_frame_type_ip.u4_timestamp_high = -1;
- s_frame_type_ip.u4_timestamp_low = -1;
-
- s_frame_type_ip.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
- s_frame_type_op.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
-
- status = ive_api_function(mCodecCtx, &s_frame_type_ip, &s_frame_type_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set frame type = 0x%x\n",
- s_frame_type_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setQp() {
- ive_ctl_set_qp_ip_t s_qp_ip;
- ive_ctl_set_qp_op_t s_qp_op;
- IV_STATUS_T status;
-
- s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
-
- s_qp_ip.u4_i_qp = DEFAULT_I_QP;
- s_qp_ip.u4_i_qp_max = DEFAULT_QP_MAX;
- s_qp_ip.u4_i_qp_min = DEFAULT_QP_MIN;
-
- s_qp_ip.u4_p_qp = DEFAULT_P_QP;
- s_qp_ip.u4_p_qp_max = DEFAULT_QP_MAX;
- s_qp_ip.u4_p_qp_min = DEFAULT_QP_MIN;
-
- s_qp_ip.u4_b_qp = DEFAULT_P_QP;
- s_qp_ip.u4_b_qp_max = DEFAULT_QP_MAX;
- s_qp_ip.u4_b_qp_min = DEFAULT_QP_MIN;
-
- s_qp_ip.u4_timestamp_high = -1;
- s_qp_ip.u4_timestamp_low = -1;
-
- s_qp_ip.u4_size = sizeof(ive_ctl_set_qp_ip_t);
- s_qp_op.u4_size = sizeof(ive_ctl_set_qp_op_t);
-
- status = ive_api_function(mCodecCtx, &s_qp_ip, &s_qp_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set qp 0x%x\n", s_qp_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setEncMode(IVE_ENC_MODE_T e_enc_mode) {
- IV_STATUS_T status;
- ive_ctl_set_enc_mode_ip_t s_enc_mode_ip;
- ive_ctl_set_enc_mode_op_t s_enc_mode_op;
-
- s_enc_mode_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_enc_mode_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
-
- s_enc_mode_ip.e_enc_mode = e_enc_mode;
-
- s_enc_mode_ip.u4_timestamp_high = -1;
- s_enc_mode_ip.u4_timestamp_low = -1;
-
- s_enc_mode_ip.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
- s_enc_mode_op.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
-
- status = ive_api_function(mCodecCtx, &s_enc_mode_ip, &s_enc_mode_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set in header encode mode = 0x%x\n",
- s_enc_mode_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setVbvParams() {
- ive_ctl_set_vbv_params_ip_t s_vbv_ip;
- ive_ctl_set_vbv_params_op_t s_vbv_op;
- IV_STATUS_T status;
-
- s_vbv_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_vbv_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
-
- s_vbv_ip.u4_vbv_buf_size = 0;
- s_vbv_ip.u4_vbv_buffer_delay = 1000;
-
- s_vbv_ip.u4_timestamp_high = -1;
- s_vbv_ip.u4_timestamp_low = -1;
-
- s_vbv_ip.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
- s_vbv_op.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
-
- status = ive_api_function(mCodecCtx, &s_vbv_ip, &s_vbv_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set VBV params = 0x%x\n", s_vbv_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setAirParams() {
- ive_ctl_set_air_params_ip_t s_air_ip;
- ive_ctl_set_air_params_op_t s_air_op;
- IV_STATUS_T status;
-
- s_air_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_air_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
-
- s_air_ip.e_air_mode =
- (mIntraRefresh->mode == C2Config::INTRA_REFRESH_DISABLED || mIntraRefresh->period < 1)
- ? IVE_AIR_MODE_NONE : IVE_AIR_MODE_CYCLIC;
- s_air_ip.u4_air_refresh_period = mIntraRefresh->period;
-
- s_air_ip.u4_timestamp_high = -1;
- s_air_ip.u4_timestamp_low = -1;
-
- s_air_ip.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
- s_air_op.u4_size = sizeof(ive_ctl_set_air_params_op_t);
-
- status = ive_api_function(mCodecCtx, &s_air_ip, &s_air_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set air params = 0x%x\n", s_air_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setMeParams() {
- IV_STATUS_T status;
- ive_ctl_set_me_params_ip_t s_me_params_ip;
- ive_ctl_set_me_params_op_t s_me_params_op;
-
- s_me_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_me_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
-
- s_me_params_ip.u4_enable_fast_sad = mEnableFastSad;
- s_me_params_ip.u4_enable_alt_ref = mEnableAltRef;
-
- s_me_params_ip.u4_enable_hpel = mHalfPelEnable;
- s_me_params_ip.u4_enable_qpel = DEFAULT_QPEL;
- s_me_params_ip.u4_me_speed_preset = DEFAULT_ME_SPEED;
- s_me_params_ip.u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
- s_me_params_ip.u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
-
- s_me_params_ip.u4_timestamp_high = -1;
- s_me_params_ip.u4_timestamp_low = -1;
-
- s_me_params_ip.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
- s_me_params_op.u4_size = sizeof(ive_ctl_set_me_params_op_t);
-
- status = ive_api_function(mCodecCtx, &s_me_params_ip, &s_me_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set me params = 0x%x\n", s_me_params_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setGopParams() {
- IV_STATUS_T status;
- ive_ctl_set_gop_params_ip_t s_gop_params_ip;
- ive_ctl_set_gop_params_op_t s_gop_params_op;
-
- s_gop_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_gop_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
-
- s_gop_params_ip.u4_i_frm_interval = mIInterval;
- s_gop_params_ip.u4_idr_frm_interval = mIDRInterval;
-
- s_gop_params_ip.u4_timestamp_high = -1;
- s_gop_params_ip.u4_timestamp_low = -1;
-
- s_gop_params_ip.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
- s_gop_params_op.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
-
- status = ive_api_function(mCodecCtx, &s_gop_params_ip, &s_gop_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set GOP params = 0x%x\n",
- s_gop_params_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setProfileParams() {
- IntfImpl::Lock lock = mIntf->lock();
-
- IV_STATUS_T status;
- ive_ctl_set_profile_params_ip_t s_profile_params_ip;
- ive_ctl_set_profile_params_op_t s_profile_params_op;
-
- s_profile_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
-
- s_profile_params_ip.e_profile = mIntf->getProfile_l();
- s_profile_params_ip.u4_entropy_coding_mode = mEntropyMode;
- s_profile_params_ip.u4_timestamp_high = -1;
- s_profile_params_ip.u4_timestamp_low = -1;
-
- s_profile_params_ip.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
- s_profile_params_op.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
- lock.unlock();
-
- status = ive_api_function(mCodecCtx, &s_profile_params_ip, &s_profile_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to set profile params = 0x%x\n",
- s_profile_params_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setDeblockParams() {
- IV_STATUS_T status;
- ive_ctl_set_deblock_params_ip_t s_deblock_params_ip;
- ive_ctl_set_deblock_params_op_t s_deblock_params_op;
-
- s_deblock_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_deblock_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
-
- s_deblock_params_ip.u4_disable_deblock_level = mDisableDeblkLevel;
-
- s_deblock_params_ip.u4_timestamp_high = -1;
- s_deblock_params_ip.u4_timestamp_low = -1;
-
- s_deblock_params_ip.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
- s_deblock_params_op.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
-
- status = ive_api_function(mCodecCtx, &s_deblock_params_ip, &s_deblock_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("Unable to enable/disable deblock params = 0x%x\n",
- s_deblock_params_op.u4_error_code);
- return C2_CORRUPTED;
- }
- return C2_OK;
-}
-
-void C2SoftAvcEnc::logVersion() {
- ive_ctl_getversioninfo_ip_t s_ctl_ip;
- ive_ctl_getversioninfo_op_t s_ctl_op;
- UWORD8 au1_buf[512];
- IV_STATUS_T status;
-
- s_ctl_ip.e_cmd = IVE_CMD_VIDEO_CTL;
- s_ctl_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
- s_ctl_ip.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
- s_ctl_op.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
- s_ctl_ip.pu1_version = au1_buf;
- s_ctl_ip.u4_version_bufsize = sizeof(au1_buf);
-
- status = ive_api_function(mCodecCtx, (void *) &s_ctl_ip, (void *) &s_ctl_op);
-
- if (status != IV_SUCCESS) {
- ALOGE("Error in getting version: 0x%x", s_ctl_op.u4_error_code);
- } else {
- ALOGV("Ittiam encoder version: %s", (char *)s_ctl_ip.pu1_version);
- }
- return;
-}
-
-c2_status_t C2SoftAvcEnc::initEncoder() {
- IV_STATUS_T status;
- WORD32 level;
-
- CHECK(!mStarted);
-
- c2_status_t errType = C2_OK;
-
- {
- IntfImpl::Lock lock = mIntf->lock();
- mSize = mIntf->getSize_l();
- mBitrate = mIntf->getBitrate_l();
- mFrameRate = mIntf->getFrameRate_l();
- mIntraRefresh = mIntf->getIntraRefresh_l();
- mAVCEncLevel = mIntf->getLevel_l();
- mIInterval = mIntf->getSyncFramePeriod_l();
- mIDRInterval = mIntf->getSyncFramePeriod_l();
- }
- uint32_t width = mSize->width;
- uint32_t height = mSize->height;
-
- mStride = width;
-
- // TODO
- mIvVideoColorFormat = IV_YUV_420P;
-
- ALOGD("Params width %d height %d level %d colorFormat %d", width,
- height, mAVCEncLevel, mIvVideoColorFormat);
-
- /* Getting Number of MemRecords */
- {
- iv_num_mem_rec_ip_t s_num_mem_rec_ip;
- iv_num_mem_rec_op_t s_num_mem_rec_op;
-
- s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t);
- s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t);
-
- s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
-
- status = ive_api_function(nullptr, &s_num_mem_rec_ip, &s_num_mem_rec_op);
-
- if (status != IV_SUCCESS) {
- ALOGE("Get number of memory records failed = 0x%x\n",
- s_num_mem_rec_op.u4_error_code);
- return C2_CORRUPTED;
- }
-
- mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
- }
-
- /* Allocate array to hold memory records */
- if (mNumMemRecords > SIZE_MAX / sizeof(iv_mem_rec_t)) {
- ALOGE("requested memory size is too big.");
- return C2_CORRUPTED;
- }
- mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
- if (nullptr == mMemRecords) {
- ALOGE("Unable to allocate memory for hold memory records: Size %zu",
- mNumMemRecords * sizeof(iv_mem_rec_t));
- mSignalledError = true;
- return C2_CORRUPTED;
- }
-
- {
- iv_mem_rec_t *ps_mem_rec;
- ps_mem_rec = mMemRecords;
- for (size_t i = 0; i < mNumMemRecords; i++) {
- ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);
- ps_mem_rec->pv_base = nullptr;
- ps_mem_rec->u4_mem_size = 0;
- ps_mem_rec->u4_mem_alignment = 0;
- ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE;
-
- ps_mem_rec++;
- }
- }
-
- /* Getting MemRecords Attributes */
- {
- iv_fill_mem_rec_ip_t s_fill_mem_rec_ip;
- iv_fill_mem_rec_op_t s_fill_mem_rec_op;
-
- s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t);
- s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t);
-
- s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
- s_fill_mem_rec_ip.ps_mem_rec = mMemRecords;
- s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords;
- s_fill_mem_rec_ip.u4_max_wd = width;
- s_fill_mem_rec_ip.u4_max_ht = height;
- s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel;
- s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT;
- s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
- s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
- s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
- s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
-
- status = ive_api_function(nullptr, &s_fill_mem_rec_ip, &s_fill_mem_rec_op);
-
- if (status != IV_SUCCESS) {
- ALOGE("Fill memory records failed = 0x%x\n",
- s_fill_mem_rec_op.u4_error_code);
- return C2_CORRUPTED;
- }
- }
-
- /* Allocating Memory for Mem Records */
- {
- WORD32 total_size;
- iv_mem_rec_t *ps_mem_rec;
- total_size = 0;
- ps_mem_rec = mMemRecords;
-
- for (size_t i = 0; i < mNumMemRecords; i++) {
- ps_mem_rec->pv_base = ive_aligned_malloc(
- ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
- if (ps_mem_rec->pv_base == nullptr) {
- ALOGE("Allocation failure for mem record id %zu size %u\n", i,
- ps_mem_rec->u4_mem_size);
- return C2_CORRUPTED;
-
- }
- total_size += ps_mem_rec->u4_mem_size;
-
- ps_mem_rec++;
- }
- }
-
- /* Codec Instance Creation */
- {
- ive_init_ip_t s_init_ip;
- ive_init_op_t s_init_op;
-
- mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
- mCodecCtx->u4_size = sizeof(iv_obj_t);
- mCodecCtx->pv_fxns = (void *)ive_api_function;
-
- s_init_ip.u4_size = sizeof(ive_init_ip_t);
- s_init_op.u4_size = sizeof(ive_init_op_t);
-
- s_init_ip.e_cmd = IV_CMD_INIT;
- s_init_ip.u4_num_mem_rec = mNumMemRecords;
- s_init_ip.ps_mem_rec = mMemRecords;
- s_init_ip.u4_max_wd = width;
- s_init_ip.u4_max_ht = height;
- s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
- s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
- s_init_ip.u4_max_level = mAVCEncLevel;
- s_init_ip.e_inp_color_fmt = mIvVideoColorFormat;
-
- if (mReconEnable || mPSNREnable) {
- s_init_ip.u4_enable_recon = 1;
- } else {
- s_init_ip.u4_enable_recon = 0;
- }
- s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
- s_init_ip.e_rc_mode = DEFAULT_RC_MODE;
- s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE;
- s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE;
- s_init_ip.u4_num_bframes = mBframes;
- s_init_ip.e_content_type = IV_PROGRESSIVE;
- s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
- s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
- s_init_ip.e_slice_mode = mSliceMode;
- s_init_ip.u4_slice_param = mSliceParam;
- s_init_ip.e_arch = mArch;
- s_init_ip.e_soc = DEFAULT_SOC;
-
- status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op);
-
- if (status != IV_SUCCESS) {
- ALOGE("Init encoder failed = 0x%x\n", s_init_op.u4_error_code);
- return C2_CORRUPTED;
- }
- }
-
- /* Get Codec Version */
- logVersion();
-
- /* set processor details */
- setNumCores();
-
- /* Video control Set Frame dimensions */
- setDimensions();
-
- /* Video control Set Frame rates */
- setFrameRate();
-
- /* Video control Set IPE Params */
- setIpeParams();
-
- /* Video control Set Bitrate */
- setBitRate();
-
- /* Video control Set QP */
- setQp();
-
- /* Video control Set AIR params */
- setAirParams();
-
- /* Video control Set VBV params */
- setVbvParams();
-
- /* Video control Set Motion estimation params */
- setMeParams();
-
- /* Video control Set GOP params */
- setGopParams();
-
- /* Video control Set Deblock params */
- setDeblockParams();
-
- /* Video control Set Profile params */
- setProfileParams();
-
- /* Video control Set in Encode header mode */
- setEncMode(IVE_ENC_MODE_HEADER);
-
- ALOGV("init_codec successfull");
-
- mSpsPpsHeaderReceived = false;
- mStarted = true;
-
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::releaseEncoder() {
- IV_STATUS_T status = IV_SUCCESS;
- iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip;
- iv_retrieve_mem_rec_op_t s_retrieve_mem_op;
- iv_mem_rec_t *ps_mem_rec;
-
- if (!mStarted) {
- return C2_OK;
- }
-
- s_retrieve_mem_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
- s_retrieve_mem_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
- s_retrieve_mem_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
- s_retrieve_mem_ip.ps_mem_rec = mMemRecords;
-
- status = ive_api_function(mCodecCtx, &s_retrieve_mem_ip, &s_retrieve_mem_op);
-
- if (status != IV_SUCCESS) {
- ALOGE("Unable to retrieve memory records = 0x%x\n",
- s_retrieve_mem_op.u4_error_code);
- return C2_CORRUPTED;
- }
-
- /* Free memory records */
- ps_mem_rec = mMemRecords;
- for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) {
- if (ps_mem_rec) ive_aligned_free(ps_mem_rec->pv_base);
- else {
- ALOGE("memory record is null.");
- return C2_CORRUPTED;
- }
- ps_mem_rec++;
- }
-
- if (mMemRecords) free(mMemRecords);
-
- // clear other pointers into the space being free()d
- mCodecCtx = nullptr;
-
- mStarted = false;
-
- return C2_OK;
-}
-
-c2_status_t C2SoftAvcEnc::setEncodeArgs(
- ive_video_encode_ip_t *ps_encode_ip,
- ive_video_encode_op_t *ps_encode_op,
- const C2GraphicView *const input,
- uint8_t *base,
- uint32_t capacity,
- uint64_t timestamp) {
- iv_raw_buf_t *ps_inp_raw_buf;
-
- ps_inp_raw_buf = &ps_encode_ip->s_inp_buf;
- ps_encode_ip->s_out_buf.pv_buf = base;
- ps_encode_ip->s_out_buf.u4_bytes = 0;
- ps_encode_ip->s_out_buf.u4_bufsize = capacity;
- ps_encode_ip->u4_size = sizeof(ive_video_encode_ip_t);
- ps_encode_op->u4_size = sizeof(ive_video_encode_op_t);
-
- ps_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE;
- ps_encode_ip->pv_bufs = nullptr;
- ps_encode_ip->pv_mb_info = nullptr;
- ps_encode_ip->pv_pic_info = nullptr;
- ps_encode_ip->u4_mb_info_type = 0;
- ps_encode_ip->u4_pic_info_type = 0;
- ps_encode_ip->u4_is_last = 0;
- ps_encode_ip->u4_timestamp_high = timestamp >> 32;
- ps_encode_ip->u4_timestamp_low = timestamp & 0xFFFFFFFF;
- ps_encode_op->s_out_buf.pv_buf = nullptr;
-
- /* Initialize color formats */
- memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t));
- ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t);
- ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
- if (input == nullptr) {
- if (mSawInputEOS){
- ps_encode_ip->u4_is_last = 1;
- }
- return C2_OK;
- }
-
- if (input->width() < mSize->width ||
- input->height() < mSize->height) {
- /* Expect width height to be configured */
- ALOGW("unexpected Capacity Aspect %d(%d) x %d(%d)", input->width(),
- mSize->width, input->height(), mSize->height);
- return C2_BAD_VALUE;
- }
- ALOGV("width = %d, height = %d", input->width(), input->height());
- const C2PlanarLayout &layout = input->layout();
- uint8_t *yPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_Y]);
- uint8_t *uPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_U]);
- uint8_t *vPlane = const_cast<uint8_t *>(input->data()[C2PlanarLayout::PLANE_V]);
- int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
- int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
- int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
-
- uint32_t width = mSize->width;
- uint32_t height = mSize->height;
- // width and height are always even (as block size is 16x16)
- CHECK_EQ((width & 1u), 0u);
- CHECK_EQ((height & 1u), 0u);
- size_t yPlaneSize = width * height;
-
- switch (layout.type) {
- case C2PlanarLayout::TYPE_RGB:
- [[fallthrough]];
- case C2PlanarLayout::TYPE_RGBA: {
- ALOGV("yPlaneSize = %zu", yPlaneSize);
- MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
- mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
- yPlane = conversionBuffer.data();
- uPlane = yPlane + yPlaneSize;
- vPlane = uPlane + yPlaneSize / 4;
- yStride = width;
- uStride = vStride = yStride / 2;
- ConvertRGBToPlanarYUV(yPlane, yStride, height, conversionBuffer.size(), *input);
- break;
- }
- case C2PlanarLayout::TYPE_YUV: {
- if (!IsYUV420(*input)) {
- ALOGE("input is not YUV420");
- return C2_BAD_VALUE;
- }
-
- if (layout.planes[layout.PLANE_Y].colInc == 1
- && layout.planes[layout.PLANE_U].colInc == 1
- && layout.planes[layout.PLANE_V].colInc == 1
- && uStride == vStride
- && yStride == 2 * vStride) {
- // I420 compatible - already set up above
- break;
- }
-
- // copy to I420
- yStride = width;
- uStride = vStride = yStride / 2;
- MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
- mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
- MediaImage2 img = CreateYUV420PlanarMediaImage2(width, height, yStride, height);
- status_t err = ImageCopy(conversionBuffer.data(), &img, *input);
- if (err != OK) {
- ALOGE("Buffer conversion failed: %d", err);
- return C2_BAD_VALUE;
- }
- yPlane = conversionBuffer.data();
- uPlane = yPlane + yPlaneSize;
- vPlane = uPlane + yPlaneSize / 4;
- break;
-
- }
-
- case C2PlanarLayout::TYPE_YUVA:
- ALOGE("YUVA plane type is not supported");
- return C2_BAD_VALUE;
-
- default:
- ALOGE("Unrecognized plane type: %d", layout.type);
- return C2_BAD_VALUE;
- }
-
- switch (mIvVideoColorFormat) {
- case IV_YUV_420P:
- {
- // input buffer is supposed to be const but Ittiam API wants bare pointer.
- ps_inp_raw_buf->apv_bufs[0] = yPlane;
- ps_inp_raw_buf->apv_bufs[1] = uPlane;
- ps_inp_raw_buf->apv_bufs[2] = vPlane;
-
- ps_inp_raw_buf->au4_wd[0] = input->width();
- ps_inp_raw_buf->au4_wd[1] = input->width() / 2;
- ps_inp_raw_buf->au4_wd[2] = input->width() / 2;
-
- ps_inp_raw_buf->au4_ht[0] = input->height();
- ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
- ps_inp_raw_buf->au4_ht[2] = input->height() / 2;
-
- ps_inp_raw_buf->au4_strd[0] = yStride;
- ps_inp_raw_buf->au4_strd[1] = uStride;
- ps_inp_raw_buf->au4_strd[2] = vStride;
- break;
- }
-
- case IV_YUV_422ILE:
- {
- // TODO
- // ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
- // ps_inp_raw_buf->au4_wd[0] = mWidth * 2;
- // ps_inp_raw_buf->au4_ht[0] = mHeight;
- // ps_inp_raw_buf->au4_strd[0] = mStride * 2;
- break;
- }
-
- case IV_YUV_420SP_UV:
- case IV_YUV_420SP_VU:
- default:
- {
- ps_inp_raw_buf->apv_bufs[0] = yPlane;
- ps_inp_raw_buf->apv_bufs[1] = uPlane;
-
- ps_inp_raw_buf->au4_wd[0] = input->width();
- ps_inp_raw_buf->au4_wd[1] = input->width();
-
- ps_inp_raw_buf->au4_ht[0] = input->height();
- ps_inp_raw_buf->au4_ht[1] = input->height() / 2;
-
- ps_inp_raw_buf->au4_strd[0] = yStride;
- ps_inp_raw_buf->au4_strd[1] = uStride;
- break;
- }
- }
- return C2_OK;
-}
-
-void C2SoftAvcEnc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- IV_STATUS_T status;
- WORD32 timeDelay, timeTaken;
- uint64_t timestamp = work->input.ordinal.timestamp.peekull();
-
- // Initialize encoder if not already initialized
- if (mCodecCtx == nullptr) {
- if (C2_OK != initEncoder()) {
- ALOGE("Failed to initialize encoder");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- if (mSignalledError) {
- return;
- }
-
- // while (!mSawOutputEOS && !outQueue.empty()) {
- c2_status_t error;
- ive_video_encode_ip_t s_encode_ip;
- ive_video_encode_op_t s_encode_op;
-
- if (!mSpsPpsHeaderReceived) {
- constexpr uint32_t kHeaderLength = MIN_STREAM_SIZE;
- uint8_t header[kHeaderLength];
- error = setEncodeArgs(
- &s_encode_ip, &s_encode_op, nullptr, header, kHeaderLength, timestamp);
- if (error != C2_OK) {
- ALOGE("setEncodeArgs failed: %d", error);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
-
- if (IV_SUCCESS != status) {
- ALOGE("Encode header failed = 0x%x\n",
- s_encode_op.u4_error_code);
- return;
- } else {
- ALOGV("Bytes Generated in header %d\n",
- s_encode_op.s_out_buf.u4_bytes);
- }
-
- mSpsPpsHeaderReceived = true;
-
- std::unique_ptr<C2StreamCsdInfo::output> csd =
- C2StreamCsdInfo::output::AllocUnique(s_encode_op.s_out_buf.u4_bytes, 0u);
- if (!csd) {
- ALOGE("CSD allocation failed");
- mSignalledError = true;
- work->result = C2_NO_MEMORY;
- return;
- }
- memcpy(csd->m.value, header, s_encode_op.s_out_buf.u4_bytes);
- work->worklets.front()->output.configUpdate.push_back(std::move(csd));
-
- DUMP_TO_FILE(
- mOutFile, csd->m.value, csd->flexCount());
- }
-
- // handle dynamic config parameters
- {
- IntfImpl::Lock lock = mIntf->lock();
- std::shared_ptr<C2StreamIntraRefreshTuning::output> intraRefresh = mIntf->getIntraRefresh_l();
- std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> requestSync = mIntf->getRequestSync_l();
- lock.unlock();
-
- if (bitrate != mBitrate) {
- mBitrate = bitrate;
- setBitRate();
- }
-
- if (intraRefresh != mIntraRefresh) {
- mIntraRefresh = intraRefresh;
- setAirParams();
- }
-
- if (requestSync != mRequestSync) {
- // we can handle IDR immediately
- if (requestSync->value) {
- // unset request
- C2StreamRequestSyncFrameTuning::output clearSync(0u, C2_FALSE);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- mIntf->config({ &clearSync }, C2_MAY_BLOCK, &failures);
- ALOGV("Got sync request");
- setFrameType(IV_IDR_FRAME);
- }
- mRequestSync = requestSync;
- }
- }
-
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- mSawInputEOS = true;
- }
-
- /* In normal mode, store inputBufferInfo and this will be returned
- when encoder consumes this input */
- // if (!mInputDataIsMeta && (inputBufferInfo != NULL)) {
- // for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) {
- // if (NULL == mInputBufferInfo[i]) {
- // mInputBufferInfo[i] = inputBufferInfo;
- // break;
- // }
- // }
- // }
- std::shared_ptr<const C2GraphicView> view;
- std::shared_ptr<C2Buffer> inputBuffer;
- if (!work->input.buffers.empty()) {
- inputBuffer = work->input.buffers[0];
- view = std::make_shared<const C2GraphicView>(
- inputBuffer->data().graphicBlocks().front().map().get());
- if (view->error() != C2_OK) {
- ALOGE("graphic view map err = %d", view->error());
- return;
- }
- }
-
- std::shared_ptr<C2LinearBlock> block;
-
- do {
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- // TODO: error handling, proper usage, etc.
- c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetch linear block err = %d", err);
- work->result = err;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error() != C2_OK) {
- ALOGE("write view map err = %d", wView.error());
- work->result = wView.error();
- return;
- }
-
- error = setEncodeArgs(
- &s_encode_ip, &s_encode_op, view.get(), wView.base(), wView.capacity(), timestamp);
- if (error != C2_OK) {
- ALOGE("setEncodeArgs failed : %d", error);
- mSignalledError = true;
- work->result = error;
- return;
- }
-
- // DUMP_TO_FILE(
- // mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],
- // (mHeight * mStride * 3 / 2));
-
- GETTIME(&mTimeStart, nullptr);
- /* Compute time elapsed between end of previous decode()
- * to start of current decode() */
- TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
- status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
-
- if (IV_SUCCESS != status) {
- if ((s_encode_op.u4_error_code & 0xFF) == IH264E_BITSTREAM_BUFFER_OVERFLOW) {
- // TODO: use IVE_CMD_CTL_GETBUFINFO for proper max input size?
- mOutBufferSize *= 2;
- continue;
- }
- ALOGE("Encode Frame failed = 0x%x\n",
- s_encode_op.u4_error_code);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- } while (IV_SUCCESS != status);
-
- // Hold input buffer reference
- if (inputBuffer) {
- mBuffers[s_encode_ip.s_inp_buf.apv_bufs[0]] = inputBuffer;
- }
-
- GETTIME(&mTimeEnd, nullptr);
- /* Compute time taken for decode() */
- TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
-
- ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
- s_encode_op.s_out_buf.u4_bytes);
-
- void *freed = s_encode_op.s_inp_buf.apv_bufs[0];
- /* If encoder frees up an input buffer, mark it as free */
- if (freed != nullptr) {
- if (mBuffers.count(freed) == 0u) {
- ALOGD("buffer not tracked");
- } else {
- // Release input buffer reference
- mBuffers.erase(freed);
- mConversionBuffersInUse.erase(freed);
- }
- }
-
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->worklets.front()->output.ordinal.timestamp =
- ((uint64_t)s_encode_op.u4_timestamp_high << 32) | s_encode_op.u4_timestamp_low;
- work->worklets.front()->output.buffers.clear();
-
- if (s_encode_op.s_out_buf.u4_bytes) {
- std::shared_ptr<C2Buffer> buffer =
- createLinearBuffer(block, 0, s_encode_op.s_out_buf.u4_bytes);
- if (IV_IDR_FRAME == s_encode_op.u4_encoded_frame_type) {
- ALOGV("IDR frame produced");
- buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
- 0u /* stream id */, C2PictureTypeKeyFrame));
- }
- work->worklets.front()->output.buffers.push_back(buffer);
- }
-
- if (s_encode_op.u4_is_last) {
- // outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
- mSawOutputEOS = true;
- } else {
- // outputBufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
- }
-}
-
-c2_status_t C2SoftAvcEnc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- // TODO: use IVE_CMD_CTL_FLUSH?
- (void)drainMode;
- (void)pool;
- return C2_OK;
-}
-
-
-class C2SoftAvcEncFactory : public C2ComponentFactory {
-public:
- C2SoftAvcEncFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftAvcEnc(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftAvcEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftAvcEnc::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftAvcEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftAvcEncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftAvcEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/avc/C2SoftAvcEnc.h b/media/codecs/avc/C2SoftAvcEnc.h
deleted file mode 100644
index aa3ca61..0000000
--- a/media/codecs/avc/C2SoftAvcEnc.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_C2_SOFT_AVC_ENC_H__
-#define ANDROID_C2_SOFT_AVC_ENC_H__
-
-#include <map>
-
-#include <utils/Vector.h>
-
-#include <SimpleC2Component.h>
-
-#include "ih264_typedefs.h"
-#include "iv2.h"
-#include "ive2.h"
-
-namespace android {
-
-#define CODEC_MAX_CORES 4
-#define LEN_STATUS_BUFFER (10 * 1024)
-#define MAX_VBV_BUFF_SIZE (120 * 16384)
-#define MAX_NUM_IO_BUFS 3
-
-#define DEFAULT_MAX_REF_FRM 2
-#define DEFAULT_MAX_REORDER_FRM 0
-#define DEFAULT_QP_MIN 10
-#define DEFAULT_QP_MAX 40
-#define DEFAULT_MAX_BITRATE 20000000
-#define DEFAULT_MAX_SRCH_RANGE_X 256
-#define DEFAULT_MAX_SRCH_RANGE_Y 256
-#define DEFAULT_MAX_FRAMERATE 120000
-#define DEFAULT_NUM_CORES 1
-#define DEFAULT_NUM_CORES_PRE_ENC 0
-#define DEFAULT_FPS 30
-#define DEFAULT_ENC_SPEED IVE_NORMAL
-
-#define DEFAULT_MEM_REC_CNT 0
-#define DEFAULT_RECON_ENABLE 0
-#define DEFAULT_CHKSUM_ENABLE 0
-#define DEFAULT_START_FRM 0
-#define DEFAULT_NUM_FRMS 0xFFFFFFFF
-#define DEFAULT_INP_COLOR_FORMAT IV_YUV_420SP_VU
-#define DEFAULT_RECON_COLOR_FORMAT IV_YUV_420P
-#define DEFAULT_LOOPBACK 0
-#define DEFAULT_SRC_FRAME_RATE 30
-#define DEFAULT_TGT_FRAME_RATE 30
-#define DEFAULT_MAX_WD 1920
-#define DEFAULT_MAX_HT 1920
-#define DEFAULT_MAX_LEVEL 41
-#define DEFAULT_STRIDE 0
-#define DEFAULT_WD 1280
-#define DEFAULT_HT 720
-#define DEFAULT_PSNR_ENABLE 0
-#define DEFAULT_ME_SPEED 100
-#define DEFAULT_ENABLE_FAST_SAD 0
-#define DEFAULT_ENABLE_ALT_REF 0
-#define DEFAULT_RC_MODE IVE_RC_STORAGE
-#define DEFAULT_BITRATE 6000000
-#define DEFAULT_I_QP 22
-#define DEFAULT_I_QP_MAX DEFAULT_QP_MAX
-#define DEFAULT_I_QP_MIN DEFAULT_QP_MIN
-#define DEFAULT_P_QP 28
-#define DEFAULT_P_QP_MAX DEFAULT_QP_MAX
-#define DEFAULT_P_QP_MIN DEFAULT_QP_MIN
-#define DEFAULT_B_QP 22
-#define DEFAULT_B_QP_MAX DEFAULT_QP_MAX
-#define DEFAULT_B_QP_MIN DEFAULT_QP_MIN
-#define DEFAULT_AIR IVE_AIR_MODE_NONE
-#define DEFAULT_AIR_REFRESH_PERIOD 30
-#define DEFAULT_SRCH_RNG_X 64
-#define DEFAULT_SRCH_RNG_Y 48
-#define DEFAULT_I_INTERVAL 30
-#define DEFAULT_IDR_INTERVAL 1000
-#define DEFAULT_B_FRAMES 0
-#define DEFAULT_DISABLE_DEBLK_LEVEL 0
-#define DEFAULT_HPEL 1
-#define DEFAULT_QPEL 1
-#define DEFAULT_I4 1
-#define DEFAULT_EPROFILE IV_PROFILE_BASE
-#define DEFAULT_ENTROPY_MODE 0
-#define DEFAULT_SLICE_MODE IVE_SLICE_MODE_NONE
-#define DEFAULT_SLICE_PARAM 256
-#define DEFAULT_ARCH ARCH_ARM_A9Q
-#define DEFAULT_SOC SOC_GENERIC
-#define DEFAULT_INTRA4x4 0
-#define STRLENGTH 500
-#define DEFAULT_CONSTRAINED_INTRA 0
-
-#define MIN(a, b) ((a) < (b))? (a) : (b)
-#define MAX(a, b) ((a) > (b))? (a) : (b)
-#define ALIGN16(x) ((((x) + 15) >> 4) << 4)
-#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
-#define ALIGN4096(x) ((((x) + 4095) >> 12) << 12)
-
-/** Used to remove warnings about unused parameters */
-#define UNUSED(x) ((void)(x))
-
-/** Get time */
-#define GETTIME(a, b) gettimeofday(a, b);
-
-/** Compute difference between start and end */
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
-#define ive_aligned_malloc(alignment, size) memalign(alignment, size)
-#define ive_aligned_free(buf) free(buf)
-
-struct C2SoftAvcEnc : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftAvcEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-protected:
- virtual ~C2SoftAvcEnc();
-
-private:
- // OMX input buffer's timestamp and flags
- typedef struct {
- int64_t mTimeUs;
- int32_t mFlags;
- } InputBufferInfo;
-
- std::shared_ptr<IntfImpl> mIntf;
-
- int32_t mStride;
-
- struct timeval mTimeStart; // Time at the start of decode()
- struct timeval mTimeEnd; // Time at the end of decode()
-
-#ifdef FILE_DUMP_ENABLE
- char mInFile[200];
- char mOutFile[200];
-#endif /* FILE_DUMP_ENABLE */
-
- IV_COLOR_FORMAT_T mIvVideoColorFormat;
-
- IV_PROFILE_T mAVCEncProfile __unused;
- WORD32 mAVCEncLevel;
- bool mStarted;
- bool mSpsPpsHeaderReceived;
-
- bool mSawInputEOS;
- bool mSawOutputEOS;
- bool mSignalledError;
- bool mIntra4x4;
- bool mEnableFastSad;
- bool mEnableAltRef;
- bool mReconEnable;
- bool mPSNREnable;
- bool mEntropyMode;
- bool mConstrainedIntraFlag;
- IVE_SPEED_CONFIG mEncSpeed;
-
- iv_obj_t *mCodecCtx; // Codec context
- iv_mem_rec_t *mMemRecords; // Memory records requested by the codec
- size_t mNumMemRecords; // Number of memory records requested by codec
- size_t mNumCores; // Number of cores used by the codec
-
- // configurations used by component in process
- // (TODO: keep this in intf but make them internal only)
- std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
- std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
- std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
- std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
-
- uint32_t mOutBufferSize;
- UWORD32 mHeaderGenerated;
- UWORD32 mBframes;
- IV_ARCH_T mArch;
- IVE_SLICE_MODE_T mSliceMode;
- UWORD32 mSliceParam;
- bool mHalfPelEnable;
- UWORD32 mIInterval;
- UWORD32 mIDRInterval;
- UWORD32 mDisableDeblkLevel;
- std::map<const void *, std::shared_ptr<C2Buffer>> mBuffers;
- MemoryBlockPool mConversionBuffers;
- std::map<const void *, MemoryBlock> mConversionBuffersInUse;
-
- void initEncParams();
- c2_status_t initEncoder();
- c2_status_t releaseEncoder();
-
- c2_status_t setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type);
- c2_status_t setQp();
- c2_status_t setEncMode(IVE_ENC_MODE_T e_enc_mode);
- c2_status_t setDimensions();
- c2_status_t setNumCores();
- c2_status_t setFrameRate();
- c2_status_t setIpeParams();
- c2_status_t setBitRate();
- c2_status_t setAirParams();
- c2_status_t setMeParams();
- c2_status_t setGopParams();
- c2_status_t setProfileParams();
- c2_status_t setDeblockParams();
- c2_status_t setVbvParams();
- void logVersion();
- c2_status_t setEncodeArgs(
- ive_video_encode_ip_t *ps_encode_ip,
- ive_video_encode_op_t *ps_encode_op,
- const C2GraphicView *const input,
- uint8_t *base,
- uint32_t capacity,
- uint64_t timestamp);
-
- C2_DO_NOT_COPY(C2SoftAvcEnc);
-};
-
-#ifdef FILE_DUMP_ENABLE
-
-#define INPUT_DUMP_PATH "/sdcard/media/avce_input"
-#define INPUT_DUMP_EXT "yuv"
-#define OUTPUT_DUMP_PATH "/sdcard/media/avce_output"
-#define OUTPUT_DUMP_EXT "h264"
-
-#define GENERATE_FILE_NAMES() { \
- GETTIME(&mTimeStart, NULL); \
- strcpy(mInFile, ""); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
- INPUT_DUMP_EXT); \
- strcpy(mOutFile, ""); \
- sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,\
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
- OUTPUT_DUMP_EXT); \
-}
-
-#define CREATE_DUMP_FILE(m_filename) { \
- FILE *fp = fopen(m_filename, "wb"); \
- if (fp != NULL) { \
- ALOGD("Opened file %s", m_filename); \
- fclose(fp); \
- } else { \
- ALOGD("Could not open file %s", m_filename); \
- } \
-}
-#define DUMP_TO_FILE(m_filename, m_buf, m_size) \
-{ \
- FILE *fp = fopen(m_filename, "ab"); \
- if (fp != NULL && m_buf != NULL) { \
- int i; \
- i = fwrite(m_buf, 1, m_size, fp); \
- ALOGD("fwrite ret %d to write %d", i, m_size); \
- if (i != (int)m_size) { \
- ALOGD("Error in fwrite, returned %d", i); \
- perror("Error in write to file"); \
- } \
- fclose(fp); \
- } else { \
- ALOGD("Could not write to file %s", m_filename);\
- if (fp != NULL) \
- fclose(fp); \
- } \
-}
-#else /* FILE_DUMP_ENABLE */
-#define INPUT_DUMP_PATH
-#define INPUT_DUMP_EXT
-#define OUTPUT_DUMP_PATH
-#define OUTPUT_DUMP_EXT
-#define GENERATE_FILE_NAMES()
-#define CREATE_DUMP_FILE(m_filename)
-#define DUMP_TO_FILE(m_filename, m_buf, m_size)
-#endif /* FILE_DUMP_ENABLE */
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_AVC_ENC_H__
diff --git a/media/codecs/base/Android.bp b/media/codecs/base/Android.bp
deleted file mode 100644
index 473cb4d..0000000
--- a/media/codecs/base/Android.bp
+++ /dev/null
@@ -1,129 +0,0 @@
-// DO NOT DEPEND ON THIS DIRECTLY
-// use libstagefright_soft_c2-defaults instead
-cc_library_shared {
- name: "libstagefright_soft_c2common",
- defaults: ["libstagefright_codec2-impl-defaults"],
- vendor_available: true,
-
- srcs: [
- "SimpleC2Component.cpp",
- "SimpleC2Interface.cpp",
- ],
-
- export_include_dirs: [
- "include",
- ],
-
- export_shared_lib_headers: [
- "libstagefright_ccodec_utils",
- ],
-
- shared_libs: [
- "libcutils", // for properties
- "liblog", // for ALOG
- "libstagefright_ccodec_utils", // for ImageCopy
- "libstagefright_foundation", // for Mutexed
- ],
-
- sanitize: {
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-
- ldflags: ["-Wl,-Bsymbolic"],
-}
-
-// public dependency for software codec implementation
-// to be used by code under media/codecs/* only as its stability is not guaranteed
-cc_defaults {
- name: "libstagefright_soft_c2-defaults",
- defaults: ["libstagefright_codec2-impl-defaults"],
- vendor_available: true,
-
- export_shared_lib_headers: [
- "libstagefright_ccodec_utils",
- ],
-
- shared_libs: [
- "libcutils", // for properties
- "liblog", // for ALOG
- "libstagefright_foundation", // for ColorUtils and MIME
- "libstagefright_ccodec_utils", // for ImageCopy
- "libstagefright_soft_c2common",
- ],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- ldflags: ["-Wl,-Bsymbolic"],
-}
-
-// public dependency for software codec implementation
-// to be used by code under media/codecs/* only
-cc_defaults {
- name: "libstagefright_soft_c2_sanitize_all-defaults",
-
- sanitize: {
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-}
-
-// public dependency for software codec implementation
-// to be used by code under media/codecs/* only
-cc_defaults {
- name: "libstagefright_soft_c2_sanitize_signed-defaults",
-
- sanitize: {
- misc_undefined: [
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-}
-
-// TEMP: used by cheets2 project - remove when no longer used
-cc_library_shared {
- name: "libstagefright_simple_c2component",
- vendor_available: true,
-
- srcs: [
- "SimpleC2Interface.cpp",
- ],
-
- local_include_dirs: [
- "include",
- ],
-
- export_include_dirs: [
- "include",
- ],
-
- shared_libs: [
- "libcutils",
- "liblog",
- "libstagefright_codec2",
- "libstagefright_codec2_vndk",
- "libstagefright_foundation",
- "libutils",
- ],
-
- sanitize: {
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- cfi: true,
- },
-
- ldflags: ["-Wl,-Bsymbolic"],
-}
-
diff --git a/media/codecs/base/SimpleC2Component.cpp b/media/codecs/base/SimpleC2Component.cpp
deleted file mode 100644
index 50b4d20..0000000
--- a/media/codecs/base/SimpleC2Component.cpp
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (C) 2017 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 "SimpleC2Component"
-#include <log/log.h>
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include <inttypes.h>
-
-#include <C2Config.h>
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <SimpleC2Component.h>
-
-namespace android {
-
-std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
- std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
- mQueue.pop_front();
- return work;
-}
-
-void SimpleC2Component::WorkQueue::push_back(std::unique_ptr<C2Work> work) {
- mQueue.push_back({ std::move(work), NO_DRAIN });
-}
-
-bool SimpleC2Component::WorkQueue::empty() const {
- return mQueue.empty();
-}
-
-void SimpleC2Component::WorkQueue::clear() {
- mQueue.clear();
-}
-
-uint32_t SimpleC2Component::WorkQueue::drainMode() const {
- return mQueue.front().drainMode;
-}
-
-void SimpleC2Component::WorkQueue::markDrain(uint32_t drainMode) {
- mQueue.push_back({ nullptr, drainMode });
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-SimpleC2Component::WorkHandler::WorkHandler() : mRunning(false) {}
-
-void SimpleC2Component::WorkHandler::setComponent(
- const std::shared_ptr<SimpleC2Component> &thiz) {
- mThiz = thiz;
-}
-
-static void Reply(const sp<AMessage> &msg, int32_t *err = nullptr) {
- sp<AReplyToken> replyId;
- CHECK(msg->senderAwaitsResponse(&replyId));
- sp<AMessage> reply = new AMessage;
- if (err) {
- reply->setInt32("err", *err);
- }
- reply->postReply(replyId);
-}
-
-void SimpleC2Component::WorkHandler::onMessageReceived(const sp<AMessage> &msg) {
- std::shared_ptr<SimpleC2Component> thiz = mThiz.lock();
- if (!thiz) {
- ALOGD("component not yet set; msg = %s", msg->debugString().c_str());
- sp<AReplyToken> replyId;
- if (msg->senderAwaitsResponse(&replyId)) {
- sp<AMessage> reply = new AMessage;
- reply->setInt32("err", C2_CORRUPTED);
- reply->postReply(replyId);
- }
- return;
- }
-
- switch (msg->what()) {
- case kWhatProcess: {
- if (mRunning) {
- if (thiz->processQueue()) {
- (new AMessage(kWhatProcess, this))->post();
- }
- } else {
- ALOGV("Ignore process message as we're not running");
- }
- break;
- }
- case kWhatInit: {
- int32_t err = thiz->onInit();
- Reply(msg, &err);
- [[fallthrough]];
- }
- case kWhatStart: {
- mRunning = true;
- break;
- }
- case kWhatStop: {
- int32_t err = thiz->onStop();
- Reply(msg, &err);
- break;
- }
- case kWhatReset: {
- thiz->onReset();
- mRunning = false;
- Reply(msg);
- break;
- }
- case kWhatRelease: {
- thiz->onRelease();
- mRunning = false;
- Reply(msg);
- break;
- }
- default: {
- ALOGD("Unrecognized msg: %d", msg->what());
- break;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-namespace {
-
-struct DummyReadView : public C2ReadView {
- DummyReadView() : C2ReadView(C2_NO_INIT) {}
-};
-
-} // namespace
-
-SimpleC2Component::SimpleC2Component(
- const std::shared_ptr<C2ComponentInterface> &intf)
- : mDummyReadView(DummyReadView()),
- mIntf(intf),
- mLooper(new ALooper),
- mHandler(new WorkHandler) {
- mLooper->setName(intf->getName().c_str());
- (void)mLooper->registerHandler(mHandler);
- mLooper->start(false, false, ANDROID_PRIORITY_VIDEO);
-}
-
-SimpleC2Component::~SimpleC2Component() {
- mLooper->unregisterHandler(mHandler->id());
- (void)mLooper->stop();
-}
-
-c2_status_t SimpleC2Component::setListener_vb(
- const std::shared_ptr<C2Component::Listener> &listener, c2_blocking_t mayBlock) {
- mHandler->setComponent(shared_from_this());
-
- Mutexed<ExecState>::Locked state(mExecState);
- if (state->mState == RUNNING) {
- if (listener) {
- return C2_BAD_STATE;
- } else if (!mayBlock) {
- return C2_BLOCKING;
- }
- }
- state->mListener = listener;
- // TODO: wait for listener change to have taken place before returning
- // (e.g. if there is an ongoing listener callback)
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::queue_nb(std::list<std::unique_ptr<C2Work>> * const items) {
- {
- Mutexed<ExecState>::Locked state(mExecState);
- if (state->mState != RUNNING) {
- return C2_BAD_STATE;
- }
- }
- bool queueWasEmpty = false;
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- queueWasEmpty = queue->empty();
- while (!items->empty()) {
- queue->push_back(std::move(items->front()));
- items->pop_front();
- }
- }
- if (queueWasEmpty) {
- (new AMessage(WorkHandler::kWhatProcess, mHandler))->post();
- }
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) {
- (void)items;
- return C2_OMITTED;
-}
-
-c2_status_t SimpleC2Component::flush_sm(
- flush_mode_t flushMode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
- (void)flushMode;
- {
- Mutexed<ExecState>::Locked state(mExecState);
- if (state->mState != RUNNING) {
- return C2_BAD_STATE;
- }
- }
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- queue->incGeneration();
- // TODO: queue->splicedBy(flushedWork, flushedWork->end());
- while (!queue->empty()) {
- std::unique_ptr<C2Work> work = queue->pop_front();
- if (work) {
- flushedWork->push_back(std::move(work));
- }
- }
- }
- {
- Mutexed<PendingWork>::Locked pending(mPendingWork);
- while (!pending->empty()) {
- flushedWork->push_back(std::move(pending->begin()->second));
- pending->erase(pending->begin());
- }
- }
-
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::drain_nb(drain_mode_t drainMode) {
- if (drainMode == DRAIN_CHAIN) {
- return C2_OMITTED;
- }
- {
- Mutexed<ExecState>::Locked state(mExecState);
- if (state->mState != RUNNING) {
- return C2_BAD_STATE;
- }
- }
- bool queueWasEmpty = false;
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- queueWasEmpty = queue->empty();
- queue->markDrain(drainMode);
- }
- if (queueWasEmpty) {
- (new AMessage(WorkHandler::kWhatProcess, mHandler))->post();
- }
-
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::start() {
- Mutexed<ExecState>::Locked state(mExecState);
- if (state->mState == RUNNING) {
- return C2_BAD_STATE;
- }
- bool needsInit = (state->mState == UNINITIALIZED);
- state.unlock();
- if (needsInit) {
- sp<AMessage> reply;
- (new AMessage(WorkHandler::kWhatInit, mHandler))->postAndAwaitResponse(&reply);
- int32_t err;
- CHECK(reply->findInt32("err", &err));
- if (err != C2_OK) {
- return (c2_status_t)err;
- }
- } else {
- (new AMessage(WorkHandler::kWhatStart, mHandler))->post();
- }
- state.lock();
- state->mState = RUNNING;
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::stop() {
- ALOGV("stop");
- {
- Mutexed<ExecState>::Locked state(mExecState);
- if (state->mState != RUNNING) {
- return C2_BAD_STATE;
- }
- state->mState = STOPPED;
- }
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- queue->clear();
- }
- {
- Mutexed<PendingWork>::Locked pending(mPendingWork);
- pending->clear();
- }
- sp<AMessage> reply;
- (new AMessage(WorkHandler::kWhatStop, mHandler))->postAndAwaitResponse(&reply);
- int32_t err;
- CHECK(reply->findInt32("err", &err));
- if (err != C2_OK) {
- return (c2_status_t)err;
- }
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::reset() {
- ALOGV("reset");
- {
- Mutexed<ExecState>::Locked state(mExecState);
- state->mState = UNINITIALIZED;
- }
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- queue->clear();
- }
- {
- Mutexed<PendingWork>::Locked pending(mPendingWork);
- pending->clear();
- }
- sp<AMessage> reply;
- (new AMessage(WorkHandler::kWhatReset, mHandler))->postAndAwaitResponse(&reply);
- return C2_OK;
-}
-
-c2_status_t SimpleC2Component::release() {
- ALOGV("release");
- sp<AMessage> reply;
- (new AMessage(WorkHandler::kWhatRelease, mHandler))->postAndAwaitResponse(&reply);
- return C2_OK;
-}
-
-std::shared_ptr<C2ComponentInterface> SimpleC2Component::intf() {
- return mIntf;
-}
-
-namespace {
-
-std::list<std::unique_ptr<C2Work>> vec(std::unique_ptr<C2Work> &work) {
- std::list<std::unique_ptr<C2Work>> ret;
- ret.push_back(std::move(work));
- return ret;
-}
-
-} // namespace
-
-void SimpleC2Component::finish(
- uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork) {
- std::unique_ptr<C2Work> work;
- {
- Mutexed<PendingWork>::Locked pending(mPendingWork);
- if (pending->count(frameIndex) == 0) {
- ALOGW("unknown frame index: %" PRIu64, frameIndex);
- return;
- }
- work = std::move(pending->at(frameIndex));
- pending->erase(frameIndex);
- }
- if (work) {
- fillWork(work);
- std::shared_ptr<C2Component::Listener> listener = mExecState.lock()->mListener;
- listener->onWorkDone_nb(shared_from_this(), vec(work));
- ALOGV("returning pending work");
- }
-}
-
-void SimpleC2Component::cloneAndSend(
- uint64_t frameIndex,
- const std::unique_ptr<C2Work> &currentWork,
- std::function<void(const std::unique_ptr<C2Work> &)> fillWork) {
- std::unique_ptr<C2Work> work(new C2Work);
- if (currentWork->input.ordinal.frameIndex == frameIndex) {
- work->input.flags = currentWork->input.flags;
- work->input.ordinal = currentWork->input.ordinal;
- } else {
- Mutexed<PendingWork>::Locked pending(mPendingWork);
- if (pending->count(frameIndex) == 0) {
- ALOGW("unknown frame index: %" PRIu64, frameIndex);
- return;
- }
- work->input.flags = pending->at(frameIndex)->input.flags;
- work->input.ordinal = pending->at(frameIndex)->input.ordinal;
- }
- work->worklets.emplace_back(new C2Worklet);
- if (work) {
- fillWork(work);
- std::shared_ptr<C2Component::Listener> listener = mExecState.lock()->mListener;
- listener->onWorkDone_nb(shared_from_this(), vec(work));
- ALOGV("cloned and sending work");
- }
-}
-
-bool SimpleC2Component::processQueue() {
- std::unique_ptr<C2Work> work;
- uint64_t generation;
- int32_t drainMode;
- bool isFlushPending = false;
- bool hasQueuedWork = false;
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- if (queue->empty()) {
- return false;
- }
-
- generation = queue->generation();
- drainMode = queue->drainMode();
- isFlushPending = queue->popPendingFlush();
- work = queue->pop_front();
- hasQueuedWork = !queue->empty();
- }
- if (isFlushPending) {
- ALOGV("processing pending flush");
- c2_status_t err = onFlush_sm();
- if (err != C2_OK) {
- ALOGD("flush err: %d", err);
- // TODO: error
- }
- }
-
- if (!mOutputBlockPool) {
- c2_status_t err = [this] {
- // TODO: don't use query_vb
- C2StreamFormatConfig::output outputFormat(0u);
- std::vector<std::unique_ptr<C2Param>> params;
- c2_status_t err = intf()->query_vb(
- { &outputFormat },
- { C2PortBlockPoolsTuning::output::PARAM_TYPE },
- C2_DONT_BLOCK,
- &params);
- if (err != C2_OK && err != C2_BAD_INDEX) {
- ALOGD("query err = %d", err);
- return err;
- }
- C2BlockPool::local_id_t poolId =
- outputFormat.value == C2FormatVideo
- ? C2BlockPool::BASIC_GRAPHIC
- : C2BlockPool::BASIC_LINEAR;
- if (params.size()) {
- C2PortBlockPoolsTuning::output *outputPools =
- C2PortBlockPoolsTuning::output::From(params[0].get());
- if (outputPools && outputPools->flexCount() >= 1) {
- poolId = outputPools->m.values[0];
- }
- }
-
- err = GetCodec2BlockPool(poolId, shared_from_this(), &mOutputBlockPool);
- ALOGD("Using output block pool with poolID %llu => got %llu - %d",
- (unsigned long long)poolId,
- (unsigned long long)(
- mOutputBlockPool ? mOutputBlockPool->getLocalId() : 111000111),
- err);
- return err;
- }();
- if (err != C2_OK) {
- Mutexed<ExecState>::Locked state(mExecState);
- std::shared_ptr<C2Component::Listener> listener = state->mListener;
- state.unlock();
- listener->onError_nb(shared_from_this(), err);
- return hasQueuedWork;
- }
- }
-
- if (!work) {
- c2_status_t err = drain(drainMode, mOutputBlockPool);
- if (err != C2_OK) {
- Mutexed<ExecState>::Locked state(mExecState);
- std::shared_ptr<C2Component::Listener> listener = state->mListener;
- state.unlock();
- listener->onError_nb(shared_from_this(), err);
- }
- return hasQueuedWork;
- }
-
- {
- std::vector<C2Param *> updates;
- for (const std::unique_ptr<C2Param> &param: work->input.configUpdate) {
- if (param) {
- updates.emplace_back(param.get());
- }
- }
- if (!updates.empty()) {
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = intf()->config_vb(updates, C2_MAY_BLOCK, &failures);
- ALOGD("applied %zu configUpdates => %s (%d)", updates.size(), asString(err), err);
- }
- }
-
- ALOGV("start processing frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
- // If input buffer list is not empty, it means we have some input to process on.
- // However, input could be a null buffer. In such case, clear the buffer list
- // before making call to process().
- if (!work->input.buffers.empty() && !work->input.buffers[0]) {
- ALOGD("Encountered null input buffer. Clearing the input buffer");
- work->input.buffers.clear();
- }
- process(work, mOutputBlockPool);
- ALOGV("processed frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
- {
- Mutexed<WorkQueue>::Locked queue(mWorkQueue);
- if (queue->generation() != generation) {
- ALOGD("work form old generation: was %" PRIu64 " now %" PRIu64,
- queue->generation(), generation);
- work->result = C2_NOT_FOUND;
- queue.unlock();
- {
- Mutexed<ExecState>::Locked state(mExecState);
- std::shared_ptr<C2Component::Listener> listener = state->mListener;
- state.unlock();
- listener->onWorkDone_nb(shared_from_this(), vec(work));
- }
- queue.lock();
- return hasQueuedWork;
- }
- }
- if (work->workletsProcessed != 0u) {
- Mutexed<ExecState>::Locked state(mExecState);
- ALOGV("returning this work");
- std::shared_ptr<C2Component::Listener> listener = state->mListener;
- state.unlock();
- listener->onWorkDone_nb(shared_from_this(), vec(work));
- } else {
- ALOGV("queue pending work");
- work->input.buffers.clear();
- std::unique_ptr<C2Work> unexpected;
- {
- Mutexed<PendingWork>::Locked pending(mPendingWork);
- uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
- if (pending->count(frameIndex) != 0) {
- unexpected = std::move(pending->at(frameIndex));
- pending->erase(frameIndex);
- }
- (void)pending->insert({ frameIndex, std::move(work) });
- }
- if (unexpected) {
- ALOGD("unexpected pending work");
- unexpected->result = C2_CORRUPTED;
- Mutexed<ExecState>::Locked state(mExecState);
- std::shared_ptr<C2Component::Listener> listener = state->mListener;
- state.unlock();
- listener->onWorkDone_nb(shared_from_this(), vec(unexpected));
- }
- }
- return hasQueuedWork;
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
- const std::shared_ptr<C2LinearBlock> &block) {
- return createLinearBuffer(block, block->offset(), block->size());
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
- const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size) {
- return C2Buffer::CreateLinearBuffer(block->share(offset, size, ::C2Fence()));
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
- const std::shared_ptr<C2GraphicBlock> &block) {
- return createGraphicBuffer(block, C2Rect(block->width(), block->height()));
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
- const std::shared_ptr<C2GraphicBlock> &block, const C2Rect &crop) {
- return C2Buffer::CreateGraphicBuffer(block->share(crop, ::C2Fence()));
-}
-
-} // namespace android
diff --git a/media/codecs/base/SimpleC2Interface.cpp b/media/codecs/base/SimpleC2Interface.cpp
deleted file mode 100644
index c849a4e..0000000
--- a/media/codecs/base/SimpleC2Interface.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2017 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 "SimpleC2Interface"
-#include <utils/Log.h>
-
-// use MediaDefs here vs. MediaCodecConstants as this is not MediaCodec specific/dependent
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <SimpleC2Interface.h>
-
-namespace android {
-
-/* SimpleInterface */
-
-SimpleInterface<void>::BaseParams::BaseParams(
- const std::shared_ptr<C2ReflectorHelper> &reflector,
- C2String name,
- C2Component::kind_t kind,
- C2Component::domain_t domain,
- C2String mediaType,
- std::vector<C2String> aliases)
- : C2InterfaceHelper(reflector) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mName, C2_PARAMKEY_COMPONENT_NAME)
- .withConstValue(AllocSharedString<C2ComponentNameSetting>(name.c_str()))
- .build());
-
- if (aliases.size()) {
- C2String joined;
- for (const C2String &alias : aliases) {
- if (joined.length()) {
- joined += ",";
- }
- joined += alias;
- }
- addParameter(
- DefineParam(mAliases, C2_PARAMKEY_COMPONENT_ALIASES)
- .withConstValue(AllocSharedString<C2ComponentAliasesSetting>(joined.c_str()))
- .build());
- }
-
- addParameter(
- DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND)
- .withConstValue(new C2ComponentKindSetting(kind))
- .build());
-
- addParameter(
- DefineParam(mDomain, C2_PARAMKEY_COMPONENT_DOMAIN)
- .withConstValue(new C2ComponentDomainSetting(domain))
- .build());
-
- // simple interfaces have single streams
- addParameter(
- DefineParam(mInputStreamCount, C2_PARAMKEY_INPUT_STREAM_COUNT)
- .withConstValue(new C2PortStreamCountTuning::input(1))
- .build());
-
- addParameter(
- DefineParam(mOutputStreamCount, C2_PARAMKEY_OUTPUT_STREAM_COUNT)
- .withConstValue(new C2PortStreamCountTuning::output(1))
- .build());
-
- // set up buffer formats and allocators
-
- // default to linear buffers and no media type
- C2BufferData::type_t rawBufferType = C2BufferData::LINEAR;
- C2String rawMediaType;
- C2Allocator::id_t rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
- C2BlockPool::local_id_t rawPoolId = C2BlockPool::BASIC_LINEAR;
- C2BufferData::type_t codedBufferType = C2BufferData::LINEAR;
- C2Allocator::id_t codedAllocator = C2AllocatorStore::DEFAULT_LINEAR;
- C2BlockPool::local_id_t codedPoolId = C2BlockPool::BASIC_LINEAR;
-
- switch (domain) {
- case C2Component::DOMAIN_IMAGE:
- case C2Component::DOMAIN_VIDEO:
- // TODO: should we define raw image? The only difference is timestamp handling
- rawBufferType = C2BufferData::GRAPHIC;
- rawMediaType = MEDIA_MIMETYPE_VIDEO_RAW;
- rawAllocator = C2AllocatorStore::DEFAULT_GRAPHIC;
- rawPoolId = C2BlockPool::BASIC_GRAPHIC;
- break;
- case C2Component::DOMAIN_AUDIO:
- rawBufferType = C2BufferData::LINEAR;
- rawMediaType = MEDIA_MIMETYPE_AUDIO_RAW;
- rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
- rawPoolId = C2BlockPool::BASIC_LINEAR;
- break;
- default:
- break;
- }
- bool isEncoder = kind == C2Component::KIND_ENCODER;
-
- // handle raw decoders
- if (mediaType == rawMediaType) {
- codedBufferType = rawBufferType;
- codedAllocator = rawAllocator;
- codedPoolId = rawPoolId;
- }
-
- addParameter(
- DefineParam(mInputFormat, C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE)
- .withConstValue(new C2StreamBufferTypeSetting::input(
- 0u, isEncoder ? rawBufferType : codedBufferType))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_PARAMKEY_INPUT_MEDIA_TYPE)
- .withConstValue(AllocSharedString<C2PortMediaTypeSetting::input>(
- isEncoder ? rawMediaType : mediaType))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_PARAMKEY_OUTPUT_STREAM_BUFFER_TYPE)
- .withConstValue(new C2StreamBufferTypeSetting::output(
- 0u, isEncoder ? codedBufferType : rawBufferType))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_PARAMKEY_OUTPUT_MEDIA_TYPE)
- .withConstValue(AllocSharedString<C2PortMediaTypeSetting::output>(
- isEncoder ? mediaType : rawMediaType))
- .build());
-
- C2Allocator::id_t inputAllocators[1] = { isEncoder ? rawAllocator : codedAllocator };
- C2Allocator::id_t outputAllocators[1] = { isEncoder ? codedAllocator : rawAllocator };
- C2BlockPool::local_id_t outputPoolIds[1] = { isEncoder ? codedPoolId : rawPoolId };
-
- addParameter(
- DefineParam(mInputAllocators, C2_PARAMKEY_INPUT_ALLOCATORS)
- .withDefault(C2PortAllocatorsTuning::input::AllocShared(inputAllocators))
- .withFields({ C2F(mInputAllocators, m.values[0]).any(),
- C2F(mInputAllocators, m.values).inRange(0, 1) })
- .withSetter(Setter<C2PortAllocatorsTuning::input>::NonStrictValuesWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mOutputAllocators, C2_PARAMKEY_OUTPUT_ALLOCATORS)
- .withDefault(C2PortAllocatorsTuning::output::AllocShared(outputAllocators))
- .withFields({ C2F(mOutputAllocators, m.values[0]).any(),
- C2F(mOutputAllocators, m.values).inRange(0, 1) })
- .withSetter(Setter<C2PortAllocatorsTuning::output>::NonStrictValuesWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mOutputPoolIds, C2_PARAMKEY_OUTPUT_BLOCK_POOLS)
- .withDefault(C2PortBlockPoolsTuning::output::AllocShared(outputPoolIds))
- .withFields({ C2F(mOutputPoolIds, m.values[0]).any(),
- C2F(mOutputPoolIds, m.values).inRange(0, 1) })
- .withSetter(Setter<C2PortBlockPoolsTuning::output>::NonStrictValuesWithNoDeps)
- .build());
-
- // add stateless params
- addParameter(
- DefineParam(mSubscribedParamIndices, C2_PARAMKEY_SUBSCRIBED_PARAM_INDICES)
- .withDefault(C2SubscribedParamIndicesTuning::AllocShared(0u))
- .withFields({ C2F(mSubscribedParamIndices, m.values[0]).any(),
- C2F(mSubscribedParamIndices, m.values).any() })
- .withSetter(Setter<C2SubscribedParamIndicesTuning>::NonStrictValuesWithNoDeps)
- .build());
-
- /* TODO
-
- addParameter(
- DefineParam(mCurrentWorkOrdinal, C2_PARAMKEY_CURRENT_WORK)
- .withDefault(new C2CurrentWorkTuning())
- .withFields({ C2F(mCurrentWorkOrdinal, m.timeStamp).any(),
- C2F(mCurrentWorkOrdinal, m.frameIndex).any(),
- C2F(mCurrentWorkOrdinal, m.customOrdinal).any() })
- .withSetter(Setter<C2CurrentWorkTuning>::NonStrictValuesWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mLastInputQueuedWorkOrdinal, C2_PARAMKEY_LAST_INPUT_QUEUED)
- .withDefault(new C2LastWorkQueuedTuning::input())
- .withFields({ C2F(mLastInputQueuedWorkOrdinal, m.timeStamp).any(),
- C2F(mLastInputQueuedWorkOrdinal, m.frameIndex).any(),
- C2F(mLastInputQueuedWorkOrdinal, m.customOrdinal).any() })
- .withSetter(Setter<C2LastWorkQueuedTuning::input>::NonStrictValuesWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mLastOutputQueuedWorkOrdinal, C2_PARAMKEY_LAST_OUTPUT_QUEUED)
- .withDefault(new C2LastWorkQueuedTuning::output())
- .withFields({ C2F(mLastOutputQueuedWorkOrdinal, m.timeStamp).any(),
- C2F(mLastOutputQueuedWorkOrdinal, m.frameIndex).any(),
- C2F(mLastOutputQueuedWorkOrdinal, m.customOrdinal).any() })
- .withSetter(Setter<C2LastWorkQueuedTuning::output>::NonStrictValuesWithNoDeps)
- .build());
-
- std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory;
-
- std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter;
- std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter;
- std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter;
-
- */
-}
-
-void SimpleInterface<void>::BaseParams::noInputLatency() {
- addParameter(
- DefineParam(mRequestedInputDelay, C2_PARAMKEY_INPUT_DELAY_REQUEST)
- .withConstValue(new C2PortRequestedDelayTuning::input(0u))
- .build());
-
- addParameter(
- DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
- .withConstValue(new C2PortActualDelayTuning::input(0u))
- .build());
-}
-
-void SimpleInterface<void>::BaseParams::noOutputLatency() {
- addParameter(
- DefineParam(mRequestedOutputDelay, C2_PARAMKEY_OUTPUT_DELAY_REQUEST)
- .withConstValue(new C2PortRequestedDelayTuning::output(0u))
- .build());
-
- addParameter(
- DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
- .withConstValue(new C2PortActualDelayTuning::output(0u))
- .build());
-}
-
-void SimpleInterface<void>::BaseParams::noPipelineLatency() {
- addParameter(
- DefineParam(mRequestedPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY_REQUEST)
- .withConstValue(new C2RequestedPipelineDelayTuning(0u))
- .build());
-
- addParameter(
- DefineParam(mActualPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY)
- .withConstValue(new C2ActualPipelineDelayTuning(0u))
- .build());
-}
-
-void SimpleInterface<void>::BaseParams::noPrivateBuffers() {
- addParameter(
- DefineParam(mPrivateAllocators, C2_PARAMKEY_PRIVATE_ALLOCATORS)
- .withConstValue(C2PrivateAllocatorsTuning::AllocShared(0u))
- .build());
-
- addParameter(
- DefineParam(mMaxPrivateBufferCount, C2_PARAMKEY_MAX_PRIVATE_BUFFER_COUNT)
- .withConstValue(C2MaxPrivateBufferCountTuning::AllocShared(0u))
- .build());
-
- addParameter(
- DefineParam(mPrivatePoolIds, C2_PARAMKEY_PRIVATE_BLOCK_POOLS)
- .withConstValue(C2PrivateBlockPoolsTuning::AllocShared(0u))
- .build());
-}
-
-void SimpleInterface<void>::BaseParams::noInputReferences() {
- addParameter(
- DefineParam(mMaxInputReferenceAge, C2_PARAMKEY_INPUT_MAX_REFERENCE_AGE)
- .withConstValue(new C2StreamMaxReferenceAgeTuning::input(0u))
- .build());
-
- addParameter(
- DefineParam(mMaxInputReferenceCount, C2_PARAMKEY_INPUT_MAX_REFERENCE_COUNT)
- .withConstValue(new C2StreamMaxReferenceCountTuning::input(0u))
- .build());
-}
-
-void SimpleInterface<void>::BaseParams::noOutputReferences() {
- addParameter(
- DefineParam(mMaxOutputReferenceAge, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_AGE)
- .withConstValue(new C2StreamMaxReferenceAgeTuning::output(0u))
- .build());
-
- addParameter(
- DefineParam(mMaxOutputReferenceCount, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_COUNT)
- .withConstValue(new C2StreamMaxReferenceCountTuning::output(0u))
- .build());
-}
-
-void SimpleInterface<void>::BaseParams::noTimeStretch() {
- addParameter(
- DefineParam(mTimeStretch, C2_PARAMKEY_TIME_STRETCH)
- .withConstValue(new C2ComponentTimeStretchTuning(1.f))
- .build());
-}
-
-/*
- Clients need to handle the following base params due to custom dependency.
-
- std::shared_ptr<C2ApiLevelSetting> mApiLevel;
- std::shared_ptr<C2ApiFeaturesSetting> mApiFeatures;
- std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
-
- std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
- std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount;
-
- std::shared_ptr<C2TrippedTuning> mTripped;
-
-*/
-
-} // namespace android
diff --git a/media/codecs/base/include/SimpleC2Component.h b/media/codecs/base/include/SimpleC2Component.h
deleted file mode 100644
index b3a98f4..0000000
--- a/media/codecs/base/include/SimpleC2Component.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef SIMPLE_C2_COMPONENT_H_
-#define SIMPLE_C2_COMPONENT_H_
-
-#include <list>
-#include <unordered_map>
-
-#include <C2Component.h>
-
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/Mutexed.h>
-
-namespace android {
-
-class SimpleC2Component
- : public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
-public:
- explicit SimpleC2Component(
- const std::shared_ptr<C2ComponentInterface> &intf);
- virtual ~SimpleC2Component();
-
- // C2Component
- // From C2Component
- virtual c2_status_t setListener_vb(
- const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) override;
- virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
- virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
- virtual c2_status_t flush_sm(
- flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
- virtual c2_status_t drain_nb(drain_mode_t mode) override;
- virtual c2_status_t start() override;
- virtual c2_status_t stop() override;
- virtual c2_status_t reset() override;
- virtual c2_status_t release() override;
- virtual std::shared_ptr<C2ComponentInterface> intf() override;
-
- // for handler
- bool processQueue();
-
-protected:
- /**
- * Initialize internal states of the component according to the config set
- * in the interface.
- *
- * This method is called during start(), but only at the first invocation or
- * after reset().
- */
- virtual c2_status_t onInit() = 0;
-
- /**
- * Stop the component.
- */
- virtual c2_status_t onStop() = 0;
-
- /**
- * Reset the component.
- */
- virtual void onReset() = 0;
-
- /**
- * Release the component.
- */
- virtual void onRelease() = 0;
-
- /**
- * Flush the component.
- */
- virtual c2_status_t onFlush_sm() = 0;
-
- /**
- * Process the given work and finish pending work using finish().
- *
- * \param[in,out] work the work to process
- * \param[in] pool the pool to use for allocating output blocks.
- */
- virtual void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) = 0;
-
- /**
- * Drain the component and finish pending work using finish().
- *
- * \param[in] drainMode mode of drain.
- * \param[in] pool the pool to use for allocating output blocks.
- *
- * \retval C2_OK The component has drained all pending output
- * work.
- * \retval C2_OMITTED Unsupported mode (e.g. DRAIN_CHAIN)
- */
- virtual c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) = 0;
-
- // for derived classes
- /**
- * Finish pending work.
- *
- * This method will retrieve the pending work according to |frameIndex| and
- * feed the work into |fillWork| function. |fillWork| must be
- * "non-blocking". Once |fillWork| returns the filled work will be returned
- * to the client.
- *
- * \param[in] frameIndex the index of the pending work
- * \param[in] fillWork the function to fill the retrieved work.
- */
- void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
-
- /**
- * Clone pending or current work and send the work back to client.
- *
- * This method will retrieve and clone the pending or current work according
- * to |frameIndex| and feed the work into |fillWork| function. |fillWork|
- * must be "non-blocking". Once |fillWork| returns the filled work will be
- * returned to the client.
- *
- * \param[in] frameIndex the index of the work
- * \param[in] currentWork the current work under processing
- * \param[in] fillWork the function to fill the retrieved work.
- */
- void cloneAndSend(
- uint64_t frameIndex,
- const std::unique_ptr<C2Work> &currentWork,
- std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
-
-
- std::shared_ptr<C2Buffer> createLinearBuffer(
- const std::shared_ptr<C2LinearBlock> &block);
-
- std::shared_ptr<C2Buffer> createLinearBuffer(
- const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size);
-
- std::shared_ptr<C2Buffer> createGraphicBuffer(
- const std::shared_ptr<C2GraphicBlock> &block);
-
- std::shared_ptr<C2Buffer> createGraphicBuffer(
- const std::shared_ptr<C2GraphicBlock> &block,
- const C2Rect &crop);
-
- static constexpr uint32_t NO_DRAIN = ~0u;
-
- C2ReadView mDummyReadView;
-
-private:
- const std::shared_ptr<C2ComponentInterface> mIntf;
-
- class WorkHandler : public AHandler {
- public:
- enum {
- kWhatProcess,
- kWhatInit,
- kWhatStart,
- kWhatStop,
- kWhatReset,
- kWhatRelease,
- };
-
- WorkHandler();
- ~WorkHandler() override = default;
-
- void setComponent(const std::shared_ptr<SimpleC2Component> &thiz);
-
- protected:
- void onMessageReceived(const sp<AMessage> &msg) override;
-
- private:
- std::weak_ptr<SimpleC2Component> mThiz;
- bool mRunning;
- };
-
- enum {
- UNINITIALIZED,
- STOPPED,
- RUNNING,
- };
-
- struct ExecState {
- ExecState() : mState(UNINITIALIZED) {}
-
- int mState;
- std::shared_ptr<C2Component::Listener> mListener;
- };
- Mutexed<ExecState> mExecState;
-
- sp<ALooper> mLooper;
- sp<WorkHandler> mHandler;
-
- class WorkQueue {
- public:
- inline WorkQueue() : mFlush(false), mGeneration(0ul) {}
-
- inline uint64_t generation() const { return mGeneration; }
- inline void incGeneration() { ++mGeneration; mFlush = true; }
-
- std::unique_ptr<C2Work> pop_front();
- void push_back(std::unique_ptr<C2Work> work);
- bool empty() const;
- uint32_t drainMode() const;
- void markDrain(uint32_t drainMode);
- inline bool popPendingFlush() {
- bool flush = mFlush;
- mFlush = false;
- return flush;
- }
- void clear();
-
- private:
- struct Entry {
- std::unique_ptr<C2Work> work;
- uint32_t drainMode;
- };
-
- bool mFlush;
- uint64_t mGeneration;
- std::list<Entry> mQueue;
- };
- Mutexed<WorkQueue> mWorkQueue;
-
- typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork;
- Mutexed<PendingWork> mPendingWork;
-
- std::shared_ptr<C2BlockPool> mOutputBlockPool;
-
- SimpleC2Component() = delete;
-};
-
-} // namespace android
-
-#endif // SIMPLE_C2_COMPONENT_H_
diff --git a/media/codecs/base/include/SimpleC2Interface.h b/media/codecs/base/include/SimpleC2Interface.h
deleted file mode 100644
index 2051d3d..0000000
--- a/media/codecs/base/include/SimpleC2Interface.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_SIMPLE_C2_INTERFACE_H_
-#define ANDROID_SIMPLE_C2_INTERFACE_H_
-
-#include <C2Component.h>
-#include <C2Config.h>
-#include <util/C2InterfaceHelper.h>
-
-namespace android {
-
-/**
- * Wrap a common interface object (such as Codec2Client::Interface, or C2InterfaceHelper into
- * a C2ComponentInterface.
- *
- * \param T common interface type
- */
-template <typename T>
-class SimpleC2Interface : public C2ComponentInterface {
-public:
- SimpleC2Interface(const char *name, c2_node_id_t id, const std::shared_ptr<T> &impl)
- : mName(name),
- mId(id),
- mImpl(impl) {
- }
-
- ~SimpleC2Interface() override = default;
-
- // From C2ComponentInterface
- C2String getName() const override { return mName; }
- c2_node_id_t getId() const override { return mId; }
- c2_status_t query_vb(
- const std::vector<C2Param*> &stackParams,
- const std::vector<C2Param::Index> &heapParamIndices,
- c2_blocking_t mayBlock,
- std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
- return mImpl->query(stackParams, heapParamIndices, mayBlock, heapParams);
- }
- c2_status_t config_vb(
- const std::vector<C2Param*> &params,
- c2_blocking_t mayBlock,
- std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
- return mImpl->config(params, mayBlock, failures);
- }
- c2_status_t createTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
- c2_status_t releaseTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
- c2_status_t querySupportedParams_nb(
- std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override {
- return mImpl->querySupportedParams(params);
- }
- c2_status_t querySupportedValues_vb(
- std::vector<C2FieldSupportedValuesQuery> &fields,
- c2_blocking_t mayBlock) const override {
- return mImpl->querySupportedValues(fields, mayBlock);
- }
-
-private:
- C2String mName;
- const c2_node_id_t mId;
- const std::shared_ptr<T> mImpl;
-};
-
-/**
- * Utility classes for common interfaces.
- */
-template<>
-class SimpleC2Interface<void> {
-public:
- /**
- * Base Codec 2.0 parameters required for all components.
- */
- struct BaseParams : C2InterfaceHelper {
- explicit BaseParams(
- const std::shared_ptr<C2ReflectorHelper> &helper,
- C2String name,
- C2Component::kind_t kind,
- C2Component::domain_t domain,
- C2String mediaType,
- std::vector<C2String> aliases = std::vector<C2String>());
-
- /// Marks that this component has no input latency. Otherwise, component must
- /// add support for C2PortRequestedDelayTuning::input and C2PortActualDelayTuning::input.
- void noInputLatency();
-
- /// Marks that this component has no output latency. Otherwise, component must
- /// add support for C2PortRequestedDelayTuning::output and C2PortActualDelayTuning::output.
- void noOutputLatency();
-
- /// Marks that this component has no pipeline latency. Otherwise, component must
- /// add support for C2RequestedPipelineDelayTuning and C2ActualPipelineDelayTuning.
- void noPipelineLatency();
-
- /// Marks that this component has no need for private buffers. Otherwise, component must
- /// add support for C2MaxPrivateBufferCountTuning, C2PrivateAllocatorsTuning and
- /// C2PrivateBlockPoolsTuning.
- void noPrivateBuffers();
-
- /// Marks that this component holds no references to input buffers. Otherwise, component
- /// must add support for C2StreamMaxReferenceAgeTuning::input and
- /// C2StreamMaxReferenceCountTuning::input.
- void noInputReferences();
-
- /// Marks that this component holds no references to output buffers. Otherwise, component
- /// must add support for C2StreamMaxReferenceAgeTuning::output and
- /// C2StreamMaxReferenceCountTuning::output.
- void noOutputReferences();
-
- /// Marks that this component does not stretch time. Otherwise, component
- /// must add support for C2ComponentTimeStretchTuning.
- void noTimeStretch();
-
- std::shared_ptr<C2ApiLevelSetting> mApiLevel;
- std::shared_ptr<C2ApiFeaturesSetting> mApiFeatures;
-
- std::shared_ptr<C2PlatformLevelSetting> mPlatformLevel;
- std::shared_ptr<C2PlatformFeaturesSetting> mPlatformFeatures;
-
- std::shared_ptr<C2ComponentNameSetting> mName;
- std::shared_ptr<C2ComponentAliasesSetting> mAliases;
- std::shared_ptr<C2ComponentKindSetting> mKind;
- std::shared_ptr<C2ComponentDomainSetting> mDomain;
- std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
- std::shared_ptr<C2ComponentTimeStretchTuning> mTimeStretch;
-
- std::shared_ptr<C2PortMediaTypeSetting::input> mInputMediaType;
- std::shared_ptr<C2PortMediaTypeSetting::output> mOutputMediaType;
- std::shared_ptr<C2StreamBufferTypeSetting::input> mInputFormat;
- std::shared_ptr<C2StreamBufferTypeSetting::output> mOutputFormat;
-
- std::shared_ptr<C2PortRequestedDelayTuning::input> mRequestedInputDelay;
- std::shared_ptr<C2PortRequestedDelayTuning::output> mRequestedOutputDelay;
- std::shared_ptr<C2RequestedPipelineDelayTuning> mRequestedPipelineDelay;
-
- std::shared_ptr<C2PortActualDelayTuning::input> mActualInputDelay;
- std::shared_ptr<C2PortActualDelayTuning::output> mActualOutputDelay;
- std::shared_ptr<C2ActualPipelineDelayTuning> mActualPipelineDelay;
-
- std::shared_ptr<C2StreamMaxReferenceAgeTuning::input> mMaxInputReferenceAge;
- std::shared_ptr<C2StreamMaxReferenceCountTuning::input> mMaxInputReferenceCount;
- std::shared_ptr<C2StreamMaxReferenceAgeTuning::output> mMaxOutputReferenceAge;
- std::shared_ptr<C2StreamMaxReferenceCountTuning::output> mMaxOutputReferenceCount;
- std::shared_ptr<C2MaxPrivateBufferCountTuning> mMaxPrivateBufferCount;
-
- std::shared_ptr<C2PortStreamCountTuning::input> mInputStreamCount;
- std::shared_ptr<C2PortStreamCountTuning::output> mOutputStreamCount;
-
- std::shared_ptr<C2SubscribedParamIndicesTuning> mSubscribedParamIndices;
- std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
- std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount;
-
- std::shared_ptr<C2CurrentWorkTuning> mCurrentWorkOrdinal;
- std::shared_ptr<C2LastWorkQueuedTuning::input> mLastInputQueuedWorkOrdinal;
- std::shared_ptr<C2LastWorkQueuedTuning::output> mLastOutputQueuedWorkOrdinal;
-
- std::shared_ptr<C2PortAllocatorsTuning::input> mInputAllocators;
- std::shared_ptr<C2PortAllocatorsTuning::output> mOutputAllocators;
- std::shared_ptr<C2PrivateAllocatorsTuning> mPrivateAllocators;
- std::shared_ptr<C2PortBlockPoolsTuning::output> mOutputPoolIds;
- std::shared_ptr<C2PrivateBlockPoolsTuning> mPrivatePoolIds;
-
- std::shared_ptr<C2TrippedTuning> mTripped;
- std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory;
-
- std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter;
- std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter;
- std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter;
- };
-};
-
-template<typename T>
-using SimpleInterface = SimpleC2Interface<T>;
-
-template<typename T, typename ...Args>
-std::shared_ptr<T> AllocSharedString(const Args(&... args), const char *str) {
- size_t len = strlen(str) + 1;
- std::shared_ptr<T> ret = T::AllocShared(len, args...);
- strcpy(ret->m.value, str);
- return ret;
-}
-
-template<typename T, typename ...Args>
-std::shared_ptr<T> AllocSharedString(const Args(&... args), const std::string &str) {
- std::shared_ptr<T> ret = T::AllocShared(str.length() + 1, args...);
- strcpy(ret->m.value, str.c_str());
- return ret;
-}
-
-template <typename T>
-struct Setter {
- typedef typename std::remove_reference<T>::type type;
-
- static C2R NonStrictValueWithNoDeps(
- bool mayBlock, C2InterfaceHelper::C2P<type> &me) {
- (void)mayBlock;
- return me.F(me.v.value).validatePossible(me.v.value);
- }
-
- static C2R NonStrictValuesWithNoDeps(
- bool mayBlock, C2InterfaceHelper::C2P<type> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- for (size_t ix = 0; ix < me.v.flexCount(); ++ix) {
- res.plus(me.F(me.v.m.values[ix]).validatePossible(me.v.m.values[ix]));
- }
- return res;
- }
-
- static C2R StrictValueWithNoDeps(
- bool mayBlock,
- const C2InterfaceHelper::C2P<type> &old,
- C2InterfaceHelper::C2P<type> &me) {
- (void)mayBlock;
- if (!me.F(me.v.value).supportsNow(me.v.value)) {
- me.set().value = old.v.value;
- }
- return me.F(me.v.value).validatePossible(me.v.value);
- }
-};
-
-} // namespace android
-
-#endif // ANDROID_SIMPLE_C2_INTERFACE_H_
diff --git a/media/codecs/cmds/Android.bp b/media/codecs/cmds/Android.bp
deleted file mode 100644
index 69142e8..0000000
--- a/media/codecs/cmds/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-cc_binary {
- name: "codec2",
- defaults: ["libstagefright_codec2-impl-defaults"],
-
- srcs: [
- "codec2.cpp",
- ],
-
- include_dirs: [
- ],
-
- shared_libs: [
- "libbase",
- "libbinder",
- "libcutils",
- "libdatasource",
- "libgui",
- "liblog",
- "libstagefright",
- "libstagefright_foundation",
- "libui",
- "libutils",
- ],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-
- sanitize: {
- cfi: true,
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- },
-}
diff --git a/media/codecs/cmds/codec2.cpp b/media/codecs/cmds/codec2.cpp
deleted file mode 100644
index 2cbbcd8..0000000
--- a/media/codecs/cmds/codec2.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <inttypes.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <thread>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "codec2"
-#include <log/log.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <datasource/DataSourceFactory.h>
-#include <media/DataSource.h>
-#include <media/IMediaHTTPService.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaExtractorFactory.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-
-#include <gui/GLConsumer.h>
-#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2Buffer.h>
-#include <C2BufferPriv.h>
-#include <C2Component.h>
-#include <C2Config.h>
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <C2Work.h>
-
-using namespace android;
-using namespace std::chrono_literals;
-
-namespace {
-
-class LinearBuffer : public C2Buffer {
-public:
- explicit LinearBuffer(const std::shared_ptr<C2LinearBlock> &block)
- : C2Buffer({ block->share(block->offset(), block->size(), ::C2Fence()) }) {}
-};
-
-class Listener;
-
-class SimplePlayer {
-public:
- SimplePlayer();
- ~SimplePlayer();
-
- void onWorkDone(std::weak_ptr<C2Component> component,
- std::list<std::unique_ptr<C2Work>> workItems);
- void onTripped(std::weak_ptr<C2Component> component,
- std::vector<std::shared_ptr<C2SettingResult>> settingResult);
- void onError(std::weak_ptr<C2Component> component, uint32_t errorCode);
-
- void play(const sp<IMediaSource> &source);
-
-private:
- typedef std::unique_lock<std::mutex> ULock;
-
- std::shared_ptr<Listener> mListener;
- std::shared_ptr<C2Component> mComponent;
-
- sp<IProducerListener> mProducerListener;
-
- std::atomic_int mLinearPoolId;
-
- std::shared_ptr<C2Allocator> mAllocIon;
- std::shared_ptr<C2BlockPool> mLinearPool;
-
- std::mutex mQueueLock;
- std::condition_variable mQueueCondition;
- std::list<std::unique_ptr<C2Work>> mWorkQueue;
-
- std::mutex mProcessedLock;
- std::condition_variable mProcessedCondition;
- std::list<std::unique_ptr<C2Work>> mProcessedWork;
-
- sp<Surface> mSurface;
- sp<SurfaceComposerClient> mComposerClient;
- sp<SurfaceControl> mControl;
-};
-
-class Listener : public C2Component::Listener {
-public:
- explicit Listener(SimplePlayer *thiz) : mThis(thiz) {}
- virtual ~Listener() = default;
-
- virtual void onWorkDone_nb(std::weak_ptr<C2Component> component,
- std::list<std::unique_ptr<C2Work>> workItems) override {
- mThis->onWorkDone(component, std::move(workItems));
- }
-
- virtual void onTripped_nb(std::weak_ptr<C2Component> component,
- std::vector<std::shared_ptr<C2SettingResult>> settingResult) override {
- mThis->onTripped(component, settingResult);
- }
-
- virtual void onError_nb(std::weak_ptr<C2Component> component,
- uint32_t errorCode) override {
- mThis->onError(component, errorCode);
- }
-
-private:
- SimplePlayer * const mThis;
-};
-
-
-SimplePlayer::SimplePlayer()
- : mListener(new Listener(this)),
- mProducerListener(new DummyProducerListener),
- mLinearPoolId(C2BlockPool::PLATFORM_START),
- mComposerClient(new SurfaceComposerClient) {
- CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
-
- std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
- CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
- mLinearPool = std::make_shared<C2PooledBlockPool>(mAllocIon, mLinearPoolId++);
-
- mControl = mComposerClient->createSurface(
- String8("A Surface"),
- 1280,
- 800,
- HAL_PIXEL_FORMAT_YV12);
- //PIXEL_FORMAT_RGB_565);
-
- CHECK(mControl != nullptr);
- CHECK(mControl->isValid());
-
- SurfaceComposerClient::Transaction{}
- .setLayer(mControl, INT_MAX)
- .show(mControl)
- .apply();
-
- mSurface = mControl->getSurface();
- CHECK(mSurface != nullptr);
- mSurface->connect(NATIVE_WINDOW_API_CPU, mProducerListener);
-}
-
-SimplePlayer::~SimplePlayer() {
- mComposerClient->dispose();
-}
-
-void SimplePlayer::onWorkDone(
- std::weak_ptr<C2Component> component, std::list<std::unique_ptr<C2Work>> workItems) {
- ALOGV("SimplePlayer::onWorkDone");
- (void) component;
- ULock l(mProcessedLock);
- for (auto & item : workItems) {
- mProcessedWork.push_back(std::move(item));
- }
- mProcessedCondition.notify_all();
-}
-
-void SimplePlayer::onTripped(
- std::weak_ptr<C2Component> component,
- std::vector<std::shared_ptr<C2SettingResult>> settingResult) {
- (void) component;
- (void) settingResult;
- // TODO
-}
-
-void SimplePlayer::onError(std::weak_ptr<C2Component> component, uint32_t errorCode) {
- (void) component;
- (void) errorCode;
- // TODO
-}
-
-void SimplePlayer::play(const sp<IMediaSource> &source) {
- ALOGV("SimplePlayer::play");
- sp<AMessage> format;
- (void) convertMetaDataToMessage(source->getFormat(), &format);
-
- sp<ABuffer> csd0, csd1;
- format->findBuffer("csd-0", &csd0);
- format->findBuffer("csd-1", &csd1);
-
- status_t err = source->start();
-
- if (err != OK) {
- fprintf(stderr, "source returned error %d (0x%08x)\n", err, err);
- return;
- }
-
- std::shared_ptr<C2ComponentStore> store = GetCodec2PlatformComponentStore();
- std::shared_ptr<C2Component> component;
- (void)store->createComponent("c2.android.avc.decoder", &component);
-
- (void)component->setListener_vb(mListener, C2_DONT_BLOCK);
- std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
- C2PortBlockPoolsTuning::output::AllocUnique({ (uint64_t)C2BlockPool::BASIC_GRAPHIC });
- std::vector<std::unique_ptr<C2SettingResult>> result;
- (void)component->intf()->config_vb({pools.get()}, C2_DONT_BLOCK, &result);
- component->start();
-
- for (int i = 0; i < 8; ++i) {
- mWorkQueue.emplace_back(new C2Work);
- }
-
- std::atomic_bool running(true);
- std::thread surfaceThread([this, &running]() {
- const sp<IGraphicBufferProducer> &igbp = mSurface->getIGraphicBufferProducer();
- while (running) {
- std::unique_ptr<C2Work> work;
- {
- ULock l(mProcessedLock);
- if (mProcessedWork.empty()) {
- mProcessedCondition.wait_for(l, 100ms);
- if (mProcessedWork.empty()) {
- continue;
- }
- }
- work.swap(mProcessedWork.front());
- mProcessedWork.pop_front();
- }
- int slot;
- sp<Fence> fence;
- ALOGV("Render: Frame #%lld", work->worklets.front()->output.ordinal.frameIndex.peekll());
- const std::shared_ptr<C2Buffer> &output = work->worklets.front()->output.buffers[0];
- if (output) {
- const C2ConstGraphicBlock block = output->data().graphicBlocks().front();
- native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(block.handle());
- sp<GraphicBuffer> buffer(new GraphicBuffer(
- grallocHandle,
- GraphicBuffer::CLONE_HANDLE,
- block.width(),
- block.height(),
- HAL_PIXEL_FORMAT_YV12,
- 1,
- (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- block.width()));
- native_handle_delete(grallocHandle);
-
- status_t err = igbp->attachBuffer(&slot, buffer);
-
- IGraphicBufferProducer::QueueBufferInput qbi(
- (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll(),
- false,
- HAL_DATASPACE_UNKNOWN,
- Rect(block.width(), block.height()),
- NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
- 0,
- Fence::NO_FENCE,
- 0);
- IGraphicBufferProducer::QueueBufferOutput qbo;
- err = igbp->queueBuffer(slot, qbi, &qbo);
- }
-
- work->input.buffers.clear();
- work->worklets.clear();
-
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- mQueueCondition.notify_all();
- }
- ALOGV("render loop finished");
- });
-
- long numFrames = 0;
- mLinearPool.reset(new C2PooledBlockPool(mAllocIon, mLinearPoolId++));
-
- for (;;) {
- size_t size = 0u;
- void *data = nullptr;
- int64_t timestamp = 0u;
- MediaBufferBase *buffer = nullptr;
- sp<ABuffer> csd;
- if (csd0 != nullptr) {
- csd = csd0;
- csd0 = nullptr;
- } else if (csd1 != nullptr) {
- csd = csd1;
- csd1 = nullptr;
- } else {
- status_t err = source->read(&buffer);
- if (err != OK) {
- CHECK(buffer == nullptr);
-
- if (err == INFO_FORMAT_CHANGED) {
- continue;
- }
-
- break;
- }
- MetaDataBase &meta = buffer->meta_data();
- CHECK(meta.findInt64(kKeyTime, &timestamp));
-
- size = buffer->size();
- data = buffer->data();
- }
-
- if (csd != nullptr) {
- size = csd->size();
- data = csd->data();
- }
-
- // Prepare C2Work
-
- std::unique_ptr<C2Work> work;
- while (!work) {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- mQueueCondition.wait_for(l, 100ms);
- }
- }
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = timestamp;
- work->input.ordinal.frameIndex = numFrames;
-
- std::shared_ptr<C2LinearBlock> block;
- mLinearPool->fetchLinearBlock(
- size,
- { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
- &block);
- C2WriteView view = block->map().get();
- if (view.error() != C2_OK) {
- fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
- break;
- }
- memcpy(view.base(), data, size);
-
- work->input.buffers.clear();
- work->input.buffers.emplace_back(new LinearBuffer(block));
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
-
- ALOGV("Frame #%ld size = %zu", numFrames, size);
- // DO THE DECODING
- component->queue_nb(&items);
-
- if (buffer) {
- buffer->release();
- buffer = nullptr;
- }
-
- ++numFrames;
- }
- ALOGV("main loop finished");
- source->stop();
- running.store(false);
- surfaceThread.join();
-
- component->release();
- printf("\n");
-}
-
-} // namespace
-
-static void usage(const char *me) {
- fprintf(stderr, "usage: %s [options] [input_filename]\n", me);
- fprintf(stderr, " -h(elp)\n");
-}
-
-int main(int argc, char **argv) {
- android::ProcessState::self()->startThreadPool();
-
- int res;
- while ((res = getopt(argc, argv, "h")) >= 0) {
- switch (res) {
- case 'h':
- default:
- {
- usage(argv[0]);
- exit(1);
- break;
- }
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc < 1) {
- fprintf(stderr, "No input file specified\n");
- return 1;
- }
-
- status_t err = OK;
- SimplePlayer player;
-
- for (int k = 0; k < argc && err == OK; ++k) {
- const char *filename = argv[k];
-
- sp<DataSource> dataSource =
- DataSourceFactory::getInstance()->CreateFromURI(nullptr /* httpService */, filename);
-
- if (strncasecmp(filename, "sine:", 5) && dataSource == nullptr) {
- fprintf(stderr, "Unable to create data source.\n");
- return 1;
- }
-
- Vector<sp<IMediaSource> > mediaSources;
- sp<IMediaSource> mediaSource;
-
- sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource);
-
- if (extractor == nullptr) {
- fprintf(stderr, "could not create extractor.\n");
- return -1;
- }
-
- sp<MetaData> meta = extractor->getMetaData();
-
- if (meta != nullptr) {
- const char *mime;
- if (!meta->findCString(kKeyMIMEType, &mime)) {
- fprintf(stderr, "extractor did not provide MIME type.\n");
- return -1;
- }
- }
-
- size_t numTracks = extractor->countTracks();
-
- size_t i;
- for (i = 0; i < numTracks; ++i) {
- meta = extractor->getTrackMetaData(i, 0);
-
- if (meta == nullptr) {
- break;
- }
- const char *mime;
- meta->findCString(kKeyMIMEType, &mime);
-
- // TODO: allowing AVC only for the time being
- if (!strncasecmp(mime, "video/avc", 9)) {
- break;
- }
-
- meta = nullptr;
- }
-
- if (meta == nullptr) {
- fprintf(stderr, "No AVC track found.\n");
- return -1;
- }
-
- mediaSource = extractor->getTrack(i);
- if (mediaSource == nullptr) {
- fprintf(stderr, "skip NULL track %zu, total tracks %zu.\n", i, numTracks);
- return -1;
- }
-
- player.play(mediaSource);
- }
-
- return 0;
-}
diff --git a/media/codecs/flac/Android.bp b/media/codecs/flac/Android.bp
deleted file mode 100644
index 32c3b36..0000000
--- a/media/codecs/flac/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2flacdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- header_libs: ["libFLAC-headers"],
-
- srcs: ["C2SoftFlacDec.cpp"],
-
- shared_libs: [
- "libstagefright_flacdec",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2flacenc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftFlacEnc.cpp"],
-
- static_libs: ["libFLAC"],
-}
diff --git a/media/codecs/flac/C2SoftFlacDec.cpp b/media/codecs/flac/C2SoftFlacDec.cpp
deleted file mode 100644
index f1e2f51..0000000
--- a/media/codecs/flac/C2SoftFlacDec.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftFlacDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftFlacDec.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.flac.decoder";
-
-class C2SoftFlacDec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_FLAC))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).inRange(1, 655350)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 8)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 768000))
- .withFields({C2F(mBitrate, value).inRange(1, 21000000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 32768))
- .build());
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftFlacDec::C2SoftFlacDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mFLACDecoder(nullptr) {
-}
-
-C2SoftFlacDec::~C2SoftFlacDec() {
- onRelease();
-}
-
-c2_status_t C2SoftFlacDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftFlacDec::onStop() {
- if (mFLACDecoder) mFLACDecoder->flush();
- memset(&mStreamInfo, 0, sizeof(mStreamInfo));
- mHasStreamInfo = false;
- mSignalledError = false;
- mSignalledOutputEos = false;
- return C2_OK;
-}
-
-void C2SoftFlacDec::onReset() {
- mInputBufferCount = 0;
- (void)onStop();
-}
-
-void C2SoftFlacDec::onRelease() {
- mInputBufferCount = 0;
- if (mFLACDecoder) delete mFLACDecoder;
- mFLACDecoder = nullptr;
-}
-
-c2_status_t C2SoftFlacDec::onFlush_sm() {
- return onStop();
-}
-
-status_t C2SoftFlacDec::initDecoder() {
- if (mFLACDecoder) {
- delete mFLACDecoder;
- }
- mFLACDecoder = FLACDecoder::Create();
- if (!mFLACDecoder) {
- ALOGE("initDecoder: failed to create FLACDecoder");
- mSignalledError = true;
- return NO_MEMORY;
- }
-
- memset(&mStreamInfo, 0, sizeof(mStreamInfo));
- mHasStreamInfo = false;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mInputBufferCount = 0;
-
- return OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-// (TODO) add multiframe support, in plugin and FLACDecoder.cpp
-void C2SoftFlacDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- C2ReadView rView = mDummyReadView;
- size_t inOffset = 0u;
- size_t inSize = 0u;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
- bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
- if (inSize == 0) {
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- if (mInputBufferCount == 0 && !codecConfig) {
- ALOGV("First frame has to include configuration, forcing config");
- codecConfig = true;
- }
-
- uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
- if (codecConfig) {
- status_t decoderErr = mFLACDecoder->parseMetadata(input, inSize);
- if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
- ALOGE("process: FLACDecoder parseMetaData returns error %d", decoderErr);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- mInputBufferCount++;
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-
- if (decoderErr == WOULD_BLOCK) {
- ALOGV("process: parseMetadata is Blocking, Continue %d", decoderErr);
- } else {
- mStreamInfo = mFLACDecoder->getStreamInfo();
- if (mStreamInfo.sample_rate && mStreamInfo.max_blocksize &&
- mStreamInfo.channels) {
- mHasStreamInfo = true;
- C2StreamSampleRateInfo::output sampleRateInfo(
- 0u, mStreamInfo.sample_rate);
- C2StreamChannelCountInfo::output channelCountInfo(
- 0u, mStreamInfo.channels);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err =
- mIntf->config({&sampleRateInfo, &channelCountInfo},
- C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(sampleRateInfo));
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(channelCountInfo));
- } else {
- ALOGE("Config Update failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- ALOGD("process: decoder configuration : %d Hz, %d channels, %d samples,"
- " %d block size", mStreamInfo.sample_rate, mStreamInfo.channels,
- (int)mStreamInfo.total_samples, mStreamInfo.max_blocksize);
- }
- return;
- }
-
- size_t outSize;
- if (mHasStreamInfo)
- outSize = mStreamInfo.max_blocksize * mStreamInfo.channels * sizeof(short);
- else
- outSize = kMaxBlockSize * FLACDecoder::kMaxChannels * sizeof(short);
-
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
-
- short *output = reinterpret_cast<short *>(wView.data());
- status_t decoderErr = mFLACDecoder->decodeOneFrame(
- input, inSize, output, &outSize);
- if (decoderErr != OK) {
- ALOGE("process: FLACDecoder decodeOneFrame returns error %d", decoderErr);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- mInputBufferCount++;
- ALOGV("out buffer attr. size %zu", outSize);
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-c2_status_t C2SoftFlacDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- if (mFLACDecoder) mFLACDecoder->flush();
-
- return C2_OK;
-}
-
-class C2SoftFlacDecFactory : public C2ComponentFactory {
-public:
- C2SoftFlacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftFlacDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftFlacDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftFlacDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftFlacDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftFlacDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftFlacDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/flac/C2SoftFlacDec.h b/media/codecs/flac/C2SoftFlacDec.h
deleted file mode 100644
index b491bfd..0000000
--- a/media/codecs/flac/C2SoftFlacDec.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_FLAC_DEC_H_
-#define ANDROID_C2_SOFT_FLAC_DEC_H_
-
-#include <SimpleC2Component.h>
-
-#include "FLACDecoder.h"
-
-namespace android {
-
-struct C2SoftFlacDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftFlacDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftFlacDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- enum {
- kMaxBlockSize = 4096
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- FLACDecoder *mFLACDecoder;
- FLAC__StreamMetadata_StreamInfo mStreamInfo;
- bool mSignalledError;
- bool mSignalledOutputEos;
- bool mHasStreamInfo;
- size_t mInputBufferCount;
-
- status_t initDecoder();
-
- C2_DO_NOT_COPY(C2SoftFlacDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_FLAC_DEC_H_
diff --git a/media/codecs/flac/C2SoftFlacEnc.cpp b/media/codecs/flac/C2SoftFlacEnc.cpp
deleted file mode 100644
index e4192c7..0000000
--- a/media/codecs/flac/C2SoftFlacEnc.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftFlacEnc"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftFlacEnc.h"
-
-namespace android {
-
-class C2SoftFlacEnc::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatAudio))
- .build());
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_FLAC))
- .build());
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::input(0u, 44100))
- .withFields({C2F(mSampleRate, value).inRange(1, 655350)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 2)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 768000))
- .withFields({C2F(mBitrate, value).inRange(1, 21000000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 4608))
- .build());
- }
-
- uint32_t getSampleRate() const { return mSampleRate->value; }
- uint32_t getChannelCount() const { return mChannelCount->value; }
- uint32_t getBitrate() const { return mBitrate->value; }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::input> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::input> mChannelCount;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-constexpr char COMPONENT_NAME[] = "c2.android.flac.encoder";
-
-C2SoftFlacEnc::C2SoftFlacEnc(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mFlacStreamEncoder(nullptr),
- mInputBufferPcm32(nullptr) {
-}
-
-C2SoftFlacEnc::~C2SoftFlacEnc() {
- onRelease();
-}
-
-c2_status_t C2SoftFlacEnc::onInit() {
- mFlacStreamEncoder = FLAC__stream_encoder_new();
- if (!mFlacStreamEncoder) return C2_CORRUPTED;
-
- mInputBufferPcm32 = (FLAC__int32*) malloc(
- kInBlockSize * kMaxNumChannels * sizeof(FLAC__int32));
- if (!mInputBufferPcm32) return C2_NO_MEMORY;
-
- mSignalledError = false;
- mSignalledOutputEos = false;
- mCompressionLevel = FLAC_COMPRESSION_LEVEL_DEFAULT;
- mIsFirstFrame = true;
- mAnchorTimeStamp = 0ull;
- mProcessedSamples = 0u;
- mEncoderWriteData = false;
- mEncoderReturnedNbBytes = 0;
- mHeaderOffset = 0;
- mWroteHeader = false;
-
- status_t err = configureEncoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-void C2SoftFlacEnc::onRelease() {
- if (mFlacStreamEncoder) {
- FLAC__stream_encoder_delete(mFlacStreamEncoder);
- mFlacStreamEncoder = nullptr;
- }
-
- if (mInputBufferPcm32) {
- free(mInputBufferPcm32);
- mInputBufferPcm32 = nullptr;
- }
-}
-
-void C2SoftFlacEnc::onReset() {
- mCompressionLevel = FLAC_COMPRESSION_LEVEL_DEFAULT;
- (void) onStop();
-}
-
-c2_status_t C2SoftFlacEnc::onStop() {
- mSignalledError = false;
- mSignalledOutputEos = false;
- mIsFirstFrame = true;
- mAnchorTimeStamp = 0ull;
- mProcessedSamples = 0u;
- mEncoderWriteData = false;
- mEncoderReturnedNbBytes = 0;
- mHeaderOffset = 0;
- mWroteHeader = false;
-
- c2_status_t status = drain(DRAIN_COMPONENT_NO_EOS, nullptr);
- if (C2_OK != status) return status;
-
- status_t err = configureEncoder();
- if (err != OK) mSignalledError = true;
- return C2_OK;
-}
-
-c2_status_t C2SoftFlacEnc::onFlush_sm() {
- return onStop();
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
-}
-
-void C2SoftFlacEnc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- C2ReadView rView = mDummyReadView;
- size_t inOffset = 0u;
- size_t inSize = 0u;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
- if (mIsFirstFrame && inSize) {
- mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
- mIsFirstFrame = false;
- }
-
- if (!mWroteHeader) {
- std::unique_ptr<C2StreamCsdInfo::output> csd =
- C2StreamCsdInfo::output::AllocUnique(mHeaderOffset, 0u);
- if (!csd) {
- ALOGE("CSD allocation failed");
- mSignalledError = true;
- work->result = C2_NO_MEMORY;
- return;
- }
- memcpy(csd->m.value, mHeader, mHeaderOffset);
- ALOGV("put csd, %d bytes", mHeaderOffset);
-
- work->worklets.front()->output.configUpdate.push_back(std::move(csd));
- mWroteHeader = true;
- }
-
- uint32_t sampleRate = mIntf->getSampleRate();
- uint32_t channelCount = mIntf->getChannelCount();
- uint64_t outTimeStamp = mProcessedSamples * 1000000ll / sampleRate;
-
- size_t outCapacity = inSize;
- outCapacity += mBlockSize * channelCount * sizeof(int16_t);
-
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &mOutputBlock);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = mOutputBlock->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
-
- mEncoderWriteData = true;
- mEncoderReturnedNbBytes = 0;
- size_t inPos = 0;
- while (inPos < inSize) {
- const uint8_t *inPtr = rView.data() + inOffset;
- size_t processSize = MIN(kInBlockSize * channelCount * sizeof(int16_t), (inSize - inPos));
- const unsigned nbInputFrames = processSize / (channelCount * sizeof(int16_t));
- const unsigned nbInputSamples = processSize / sizeof(int16_t);
- const int16_t *pcm16 = reinterpret_cast<const int16_t *>(inPtr + inPos);
- ALOGV("about to encode %zu bytes", processSize);
-
- for (unsigned i = 0; i < nbInputSamples; i++) {
- mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
- }
-
- FLAC__bool ok = FLAC__stream_encoder_process_interleaved(
- mFlacStreamEncoder, mInputBufferPcm32, nbInputFrames);
- if (!ok) {
- ALOGE("error encountered during encoding");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- mOutputBlock.reset();
- return;
- }
- inPos += processSize;
- }
- if (eos && (C2_OK != drain(DRAIN_COMPONENT_WITH_EOS, pool))) {
- ALOGE("error encountered during encoding");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- mOutputBlock.reset();
- return;
- }
- fillEmptyWork(work);
- if (mEncoderReturnedNbBytes != 0) {
- std::shared_ptr<C2Buffer> buffer = createLinearBuffer(std::move(mOutputBlock), 0, mEncoderReturnedNbBytes);
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
- } else {
- ALOGV("encoder process_interleaved returned without data to write");
- }
- mOutputBlock = nullptr;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- mEncoderWriteData = false;
- mEncoderReturnedNbBytes = 0;
-}
-
-FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::onEncodedFlacAvailable(
- const FLAC__byte buffer[], size_t bytes, unsigned samples,
- unsigned current_frame) {
- (void) current_frame;
- ALOGV("%s (bytes=%zu, samples=%u, curr_frame=%u)", __func__, bytes, samples,
- current_frame);
-
- if (samples == 0) {
- ALOGI("saving %zu bytes of header", bytes);
- memcpy(mHeader + mHeaderOffset, buffer, bytes);
- mHeaderOffset += bytes;// will contain header size when finished receiving header
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
- }
-
- if ((samples == 0) || !mEncoderWriteData) {
- // called by the encoder because there's header data to save, but it's not the role
- // of this component (unless WRITE_FLAC_HEADER_IN_FIRST_BUFFER is defined)
- ALOGV("ignoring %zu bytes of header data (samples=%d)", bytes, samples);
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
- }
-
- // write encoded data
- C2WriteView wView = mOutputBlock->map().get();
- uint8_t* outData = wView.data();
- ALOGV("writing %zu bytes of encoded data on output", bytes);
- // increment mProcessedSamples to maintain audio synchronization during
- // play back
- mProcessedSamples += samples;
- if (bytes + mEncoderReturnedNbBytes > mOutputBlock->capacity()) {
- ALOGE("not enough space left to write encoded data, dropping %zu bytes", bytes);
- // a fatal error would stop the encoding
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
- }
- memcpy(outData + mEncoderReturnedNbBytes, buffer, bytes);
- mEncoderReturnedNbBytes += bytes;
- return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
-}
-
-
-status_t C2SoftFlacEnc::configureEncoder() {
- ALOGV("%s numChannel=%d, sampleRate=%d", __func__, mIntf->getChannelCount(), mIntf->getSampleRate());
-
- if (mSignalledError || !mFlacStreamEncoder) {
- ALOGE("can't configure encoder: no encoder or invalid state");
- return UNKNOWN_ERROR;
- }
-
- FLAC__bool ok = true;
- ok = ok && FLAC__stream_encoder_set_channels(mFlacStreamEncoder, mIntf->getChannelCount());
- ok = ok && FLAC__stream_encoder_set_sample_rate(mFlacStreamEncoder, mIntf->getSampleRate());
- ok = ok && FLAC__stream_encoder_set_bits_per_sample(mFlacStreamEncoder, 16);
- ok = ok && FLAC__stream_encoder_set_compression_level(mFlacStreamEncoder, mCompressionLevel);
- ok = ok && FLAC__stream_encoder_set_verify(mFlacStreamEncoder, false);
- if (!ok) {
- ALOGE("unknown error when configuring encoder");
- return UNKNOWN_ERROR;
- }
-
- ok &= FLAC__STREAM_ENCODER_INIT_STATUS_OK ==
- FLAC__stream_encoder_init_stream(mFlacStreamEncoder,
- flacEncoderWriteCallback /*write_callback*/,
- nullptr /*seek_callback*/,
- nullptr /*tell_callback*/,
- nullptr /*metadata_callback*/,
- (void *) this /*client_data*/);
-
- if (!ok) {
- ALOGE("unknown error when configuring encoder");
- return UNKNOWN_ERROR;
- }
-
- mBlockSize = FLAC__stream_encoder_get_blocksize(mFlacStreamEncoder);
-
- ALOGV("encoder successfully configured");
- return OK;
-}
-
-FLAC__StreamEncoderWriteStatus C2SoftFlacEnc::flacEncoderWriteCallback(
- const FLAC__StreamEncoder *,
- const FLAC__byte buffer[],
- size_t bytes,
- unsigned samples,
- unsigned current_frame,
- void *client_data) {
- return ((C2SoftFlacEnc*) client_data)->onEncodedFlacAvailable(
- buffer, bytes, samples, current_frame);
-}
-
-c2_status_t C2SoftFlacEnc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- switch (drainMode) {
- case NO_DRAIN:
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- case DRAIN_CHAIN:
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- case DRAIN_COMPONENT_WITH_EOS:
- // TODO: This flag is not being sent back to the client
- // because there are no items in PendingWork queue as all the
- // inputs are being sent back with emptywork or valid encoded data
- // mSignalledOutputEos = true;
- case DRAIN_COMPONENT_NO_EOS:
- break;
- default:
- return C2_BAD_VALUE;
- }
- FLAC__bool ok = FLAC__stream_encoder_finish(mFlacStreamEncoder);
- if (!ok) return C2_CORRUPTED;
- mIsFirstFrame = true;
- mAnchorTimeStamp = 0ull;
- mProcessedSamples = 0u;
-
- return C2_OK;
-}
-
-class C2SoftFlacEncFactory : public C2ComponentFactory {
-public:
- C2SoftFlacEncFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftFlacEnc(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftFlacEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftFlacEnc::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftFlacEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftFlacEncFactory() override = default;
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftFlacEncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/flac/C2SoftFlacEnc.h b/media/codecs/flac/C2SoftFlacEnc.h
deleted file mode 100644
index cdf305e..0000000
--- a/media/codecs/flac/C2SoftFlacEnc.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_FLAC_ENC_H_
-#define ANDROID_C2_SOFT_FLAC_ENC_H_
-
-#include <SimpleC2Component.h>
-
-#include "FLAC/stream_encoder.h"
-
-#define FLAC_COMPRESSION_LEVEL_MIN 0
-#define FLAC_COMPRESSION_LEVEL_DEFAULT 5
-#define FLAC_COMPRESSION_LEVEL_MAX 8
-
-#define FLAC_HEADER_SIZE 128
-
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
-namespace android {
-
-class C2SoftFlacEnc : public SimpleC2Component {
-public:
- class IntfImpl;
-
- C2SoftFlacEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftFlacEnc();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- status_t configureEncoder();
- static FLAC__StreamEncoderWriteStatus flacEncoderWriteCallback(
- const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[],
- size_t bytes, unsigned samples, unsigned current_frame,
- void *client_data);
- FLAC__StreamEncoderWriteStatus onEncodedFlacAvailable(
- const FLAC__byte buffer[], size_t bytes, unsigned samples,
- unsigned current_frame);
-
- std::shared_ptr<IntfImpl> mIntf;
- const unsigned int kInBlockSize = 1152;
- const unsigned int kMaxNumChannels = 2;
- FLAC__StreamEncoder* mFlacStreamEncoder;
- FLAC__int32* mInputBufferPcm32;
- std::shared_ptr<C2LinearBlock> mOutputBlock;
- bool mSignalledError;
- bool mSignalledOutputEos;
- uint32_t mCompressionLevel;
- uint32_t mBlockSize;
- bool mIsFirstFrame;
- uint64_t mAnchorTimeStamp;
- uint64_t mProcessedSamples;
- // should the data received by the callback be written to the output port
- bool mEncoderWriteData;
- size_t mEncoderReturnedNbBytes;
- unsigned mHeaderOffset;
- bool mWroteHeader;
- char mHeader[FLAC_HEADER_SIZE];
-
- C2_DO_NOT_COPY(C2SoftFlacEnc);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_FLAC_ENC_H_
diff --git a/media/codecs/flac/MODULE_LICENSE_APACHE2 b/media/codecs/flac/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/flac/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/flac/NOTICE b/media/codecs/flac/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/flac/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/g711/Android.bp b/media/codecs/g711/Android.bp
deleted file mode 100644
index 56cbc20..0000000
--- a/media/codecs/g711/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2g711alawdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftG711Dec.cpp"],
-
- cflags: [
- "-DALAW",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2g711mlawdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftG711Dec.cpp"],
-}
diff --git a/media/codecs/g711/C2SoftG711Dec.cpp b/media/codecs/g711/C2SoftG711Dec.cpp
deleted file mode 100644
index 1c71d45..0000000
--- a/media/codecs/g711/C2SoftG711Dec.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftG711Dec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftG711Dec.h"
-
-namespace android {
-
-#ifdef ALAW
-constexpr char COMPONENT_NAME[] = "c2.android.g711.alaw.decoder";
-#else
-constexpr char COMPONENT_NAME[] = "c2.android.g711.mlaw.decoder";
-#endif
-
-class C2SoftG711Dec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
-#ifdef ALAW
- MEDIA_MIMETYPE_AUDIO_G711_ALAW
-#else
- MEDIA_MIMETYPE_AUDIO_G711_MLAW
-#endif
- )).build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
- .withFields({C2F(mSampleRate, value).inRange(8000, 48000)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).equalTo(1)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 64000))
- .withFields({C2F(mBitrate, value).equalTo(64000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftG711Dec::C2SoftG711Dec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl) {
-}
-
-C2SoftG711Dec::~C2SoftG711Dec() {
- onRelease();
-}
-
-c2_status_t C2SoftG711Dec::onInit() {
- mSignalledOutputEos = false;
- return C2_OK;
-}
-
-c2_status_t C2SoftG711Dec::onStop() {
- mSignalledOutputEos = false;
- return C2_OK;
-}
-
-void C2SoftG711Dec::onReset() {
- (void)onStop();
-}
-
-void C2SoftG711Dec::onRelease() {
-}
-
-c2_status_t C2SoftG711Dec::onFlush_sm() {
- return onStop();
-}
-
-void C2SoftG711Dec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- C2ReadView rView = mDummyReadView;
- size_t inOffset = 0u;
- size_t inSize = 0u;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
- int outSize = inSize * sizeof(int16_t);
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
- if (inSize == 0) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- uint8_t *inputptr = const_cast<uint8_t *>(rView.data() + inOffset);
-
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- int16_t *outputptr = reinterpret_cast<int16_t *>(wView.data());
-
-#ifdef ALAW
- DecodeALaw(outputptr, inputptr, inSize);
-#else
- DecodeMLaw(outputptr, inputptr, inSize);
-#endif
-
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(createLinearBuffer(block));
- work->worklets.front()->output.ordinal = work->input.ordinal;
-
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-c2_status_t C2SoftG711Dec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-#ifdef ALAW
-void C2SoftG711Dec::DecodeALaw(
- int16_t *out, const uint8_t *in, size_t inSize) {
- while (inSize > 0) {
- inSize--;
- int32_t x = *in++;
-
- int32_t ix = x ^ 0x55;
- ix &= 0x7f;
-
- int32_t iexp = ix >> 4;
- int32_t mant = ix & 0x0f;
-
- if (iexp > 0) {
- mant += 16;
- }
-
- mant = (mant << 4) + 8;
-
- if (iexp > 1) {
- mant = mant << (iexp - 1);
- }
-
- *out++ = (x > 127) ? mant : -mant;
- }
-}
-#else
-void C2SoftG711Dec::DecodeMLaw(
- int16_t *out, const uint8_t *in, size_t inSize) {
- while (inSize > 0) {
- inSize--;
- int32_t x = *in++;
-
- int32_t mantissa = ~x;
- int32_t exponent = (mantissa >> 4) & 7;
- int32_t segment = exponent + 1;
- mantissa &= 0x0f;
-
- int32_t step = 4 << segment;
-
- int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33;
-
- *out++ = (x < 0x80) ? -abs : abs;
- }
-}
-#endif
-
-class C2SoftG711DecFactory : public C2ComponentFactory {
-public:
- C2SoftG711DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftG711Dec(COMPONENT_NAME, id,
- std::make_shared<C2SoftG711Dec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftG711Dec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftG711Dec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftG711DecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftG711DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/g711/C2SoftG711Dec.h b/media/codecs/g711/C2SoftG711Dec.h
deleted file mode 100644
index 23e8ffc..0000000
--- a/media/codecs/g711/C2SoftG711Dec.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_G711_DEC_H_
-#define ANDROID_C2_SOFT_G711_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-namespace android {
-
-struct C2SoftG711Dec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftG711Dec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftG711Dec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-private:
- std::shared_ptr<IntfImpl> mIntf;
- bool mSignalledOutputEos;
-
-#ifdef ALAW
- void DecodeALaw(int16_t *out, const uint8_t *in, size_t inSize);
-#else
- void DecodeMLaw(int16_t *out, const uint8_t *in, size_t inSize);
-#endif
-
- C2_DO_NOT_COPY(C2SoftG711Dec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_G711_DEC_H_
diff --git a/media/codecs/g711/MODULE_LICENSE_APACHE2 b/media/codecs/g711/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/g711/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/g711/NOTICE b/media/codecs/g711/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/g711/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/gsm/Android.bp b/media/codecs/gsm/Android.bp
deleted file mode 100644
index 8075747..0000000
--- a/media/codecs/gsm/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2gsmdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftGsmDec.cpp"],
-
- static_libs: ["libgsm"],
-}
diff --git a/media/codecs/gsm/C2SoftGsmDec.cpp b/media/codecs/gsm/C2SoftGsmDec.cpp
deleted file mode 100644
index 7101c79..0000000
--- a/media/codecs/gsm/C2SoftGsmDec.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftGsmDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftGsmDec.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.gsm.decoder";
-
-class C2SoftGsmDec::IntfImpl : public C2InterfaceHelper {
- public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_MSGSM))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 8000))
- .withFields({C2F(mSampleRate, value).equalTo(8000)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).equalTo(1)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 13200))
- .withFields({C2F(mBitrate, value).equalTo(13200)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 1024 / MSGSM_IN_FRM_SZ * MSGSM_IN_FRM_SZ))
- .build());
- }
-
- private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftGsmDec::C2SoftGsmDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : SimpleC2Component(
- std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mGsm(nullptr) {
-}
-
-C2SoftGsmDec::~C2SoftGsmDec() {
- onRelease();
-}
-
-c2_status_t C2SoftGsmDec::onInit() {
- if (!mGsm) mGsm = gsm_create();
- if (!mGsm) return C2_NO_MEMORY;
- int msopt = 1;
- (void)gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
- mSignalledError = false;
- mSignalledEos = false;
- return C2_OK;
-}
-
-c2_status_t C2SoftGsmDec::onStop() {
- if (mGsm) {
- gsm_destroy(mGsm);
- mGsm = nullptr;
- }
- if (!mGsm) mGsm = gsm_create();
- if (!mGsm) return C2_NO_MEMORY;
- int msopt = 1;
- (void)gsm_option(mGsm, GSM_OPT_WAV49, &msopt);
- mSignalledError = false;
- mSignalledEos = false;
- return C2_OK;
-}
-
-void C2SoftGsmDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftGsmDec::onRelease() {
- if (mGsm) {
- gsm_destroy(mGsm);
- mGsm = nullptr;
- }
-}
-
-c2_status_t C2SoftGsmDec::onFlush_sm() {
- return onStop();
-}
-
-static size_t decodeGSM(gsm handle, int16_t *out, size_t outCapacity,
- uint8_t *in, size_t inSize) {
- size_t outSize = 0;
-
- if (inSize % MSGSM_IN_FRM_SZ == 0
- && (inSize / MSGSM_IN_FRM_SZ * MSGSM_OUT_FRM_SZ * sizeof(*out)
- <= outCapacity)) {
- while (inSize > 0) {
- gsm_decode(handle, in, out);
- in += FRGSM_IN_FRM_SZ;
- inSize -= FRGSM_IN_FRM_SZ;
- out += FRGSM_OUT_FRM_SZ;
- outSize += FRGSM_OUT_FRM_SZ;
-
- gsm_decode(handle, in, out);
- in += FRGSM_IN_FRM_SZ_MINUS_1;
- inSize -= FRGSM_IN_FRM_SZ_MINUS_1;
- out += FRGSM_OUT_FRM_SZ;
- outSize += FRGSM_OUT_FRM_SZ;
- }
- }
-
- return outSize * sizeof(int16_t);
-}
-
-void C2SoftGsmDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- C2ReadView rView = mDummyReadView;
- size_t inOffset = 0u;
- size_t inSize = 0u;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
-
- if (inSize == 0) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (eos) {
- mSignalledEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
- size_t outCapacity = (inSize / MSGSM_IN_FRM_SZ ) * MSGSM_OUT_FRM_SZ * sizeof(int16_t);
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
-
- int16_t *output = reinterpret_cast<int16_t *>(wView.data());
- uint8_t *input = const_cast<uint8_t *>(rView.data() + inOffset);
- size_t outSize = decodeGSM(mGsm, output, outCapacity, input, inSize);
- if (!outSize) {
- ALOGE("encountered improper insize or outsize");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- ALOGV("out buffer attr. size %zu", outSize);
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (eos) {
- mSignalledEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-c2_status_t C2SoftGsmDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-class C2SoftGSMDecFactory : public C2ComponentFactory {
-public:
- C2SoftGSMDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftGsmDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftGsmDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftGsmDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftGsmDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftGSMDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftGSMDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/gsm/C2SoftGsmDec.h b/media/codecs/gsm/C2SoftGsmDec.h
deleted file mode 100644
index 2b209fe..0000000
--- a/media/codecs/gsm/C2SoftGsmDec.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_GSM_DEC_H_
-#define ANDROID_C2_SOFT_GSM_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-extern "C" {
- #include "gsm.h"
-}
-
-namespace android {
-
-#define FRGSM_IN_FRM_SZ 33
-#define FRGSM_IN_FRM_SZ_MINUS_1 32
-#define FRGSM_OUT_FRM_SZ 160
-#define MSGSM_IN_FRM_SZ (FRGSM_IN_FRM_SZ + FRGSM_IN_FRM_SZ_MINUS_1)
-#define MSGSM_OUT_FRM_SZ (FRGSM_OUT_FRM_SZ * 2)
-
-struct C2SoftGsmDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftGsmDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftGsmDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
- private:
- std::shared_ptr<IntfImpl> mIntf;
- gsm mGsm;
- bool mSignalledError;
- bool mSignalledEos;
-
- C2_DO_NOT_COPY(C2SoftGsmDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_GSM_DEC_H_
diff --git a/media/codecs/gsm/MODULE_LICENSE_APACHE2 b/media/codecs/gsm/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/gsm/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/gsm/NOTICE b/media/codecs/gsm/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/gsm/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/hevc/Android.bp b/media/codecs/hevc/Android.bp
deleted file mode 100644
index 519de68..0000000
--- a/media/codecs/hevc/Android.bp
+++ /dev/null
@@ -1,16 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2hevcdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- srcs: ["C2SoftHevcDec.cpp"],
-
- static_libs: ["libhevcdec"],
-
- include_dirs: [
- "external/libhevc/decoder",
- "external/libhevc/common",
- ],
-}
diff --git a/media/codecs/hevc/C2SoftHevcDec.cpp b/media/codecs/hevc/C2SoftHevcDec.cpp
deleted file mode 100644
index 99892ce..0000000
--- a/media/codecs/hevc/C2SoftHevcDec.cpp
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftHevcDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <Codec2Mapper.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftHevcDec.h"
-#include "ihevcd_cxa.h"
-
-namespace android {
-
-namespace {
-
-constexpr char COMPONENT_NAME[] = "c2.android.hevc.decoder";
-
-} // namespace
-
-class C2SoftHevcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : SimpleInterface<void>::BaseParams(
- helper,
- COMPONENT_NAME,
- C2Component::KIND_DECODER,
- C2Component::DOMAIN_VIDEO,
- MEDIA_MIMETYPE_VIDEO_HEVC) {
- noPrivateBuffers(); // TODO: account for our buffers here
- noInputReferences();
- noOutputReferences();
- noInputLatency();
- noTimeStretch();
-
- // TODO: output latency and reordering
-
- addParameter(
- DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
- .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 4096, 2),
- C2F(mSize, height).inRange(2, 4096, 2),
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_HEVC_MAIN, C2Config::LEVEL_HEVC_MAIN_5_1))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_HEVC_MAIN,
- C2Config::PROFILE_HEVC_MAIN_STILL}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_HEVC_MAIN_1,
- C2Config::LEVEL_HEVC_MAIN_2, C2Config::LEVEL_HEVC_MAIN_2_1,
- C2Config::LEVEL_HEVC_MAIN_3, C2Config::LEVEL_HEVC_MAIN_3_1,
- C2Config::LEVEL_HEVC_MAIN_4, C2Config::LEVEL_HEVC_MAIN_4_1,
- C2Config::LEVEL_HEVC_MAIN_5, C2Config::LEVEL_HEVC_MAIN_5_1,
- C2Config::LEVEL_HEVC_MAIN_5_2, C2Config::LEVEL_HEVC_HIGH_4,
- C2Config::LEVEL_HEVC_HIGH_4_1, C2Config::LEVEL_HEVC_HIGH_5,
- C2Config::LEVEL_HEVC_HIGH_5_1, C2Config::LEVEL_HEVC_HIGH_5_2
- })
- })
- .withSetter(ProfileLevelSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
- .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 4096, 2),
- C2F(mSize, height).inRange(2, 4096, 2),
- })
- .withSetter(MaxPictureSizeSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
- .withFields({
- C2F(mMaxInputSize, value).any(),
- })
- .calculatedAs(MaxInputSizeSetter, mMaxSize)
- .build());
-
- C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
- std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- 1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
- memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
-
- defaultColorInfo = C2StreamColorInfo::output::AllocShared(
- {C2ChromaOffsetStruct::ITU_YUV_420_0()}, 0u, 8u /* bitDepth */,
- C2Color::YUV_420);
- helper->addStructDescriptors<C2ChromaOffsetStruct>();
-
- addParameter(
- DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
- .withConstValue(defaultColorInfo)
- .build());
-
- addParameter(
- DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsTuning::output(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mDefaultColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mDefaultColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mDefaultColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mDefaultColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(DefaultColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::input(
- 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mCodedColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mCodedColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mCodedColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mCodedColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(CodedColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::output(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
- .build());
-
- // TODO: support more formats?
- addParameter(
- DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
- .build());
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
- C2P<C2VideoSizeStreamInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- // TODO: get max width/height from the size's field helpers vs. hardcoding
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 4096u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 4096u);
- return C2R::Ok();
- }
-
- static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
- const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
- (void)mayBlock;
- // assume compression ratio of 2
- me.set().value = (((maxSize.v.width + 63) / 64) * ((maxSize.v.height + 63) / 64) * 3072);
- return C2R::Ok();
- }
-
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- (void)size;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
- }
-
- static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
- }
-
- static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
- const C2P<C2StreamColorAspectsTuning::output> &def,
- const C2P<C2StreamColorAspectsInfo::input> &coded) {
- (void)mayBlock;
- // take default values for all unspecified fields, and coded values for specified ones
- me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
- me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
- ? def.v.primaries : coded.v.primaries;
- me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
- ? def.v.transfer : coded.v.transfer;
- me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
- return C2R::Ok();
- }
-
- std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
- return mColorAspects;
- }
-
-private:
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
- std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
- std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
- std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
- std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
- std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
- std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
-};
-
-static size_t getCpuCoreCount() {
- long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
- cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- // _SC_NPROC_ONLN must be defined...
- cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
- CHECK(cpuCoreCount >= 1);
- ALOGV("Number of CPU cores: %ld", cpuCoreCount);
- return (size_t)cpuCoreCount;
-}
-
-static void *ivd_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
- (void) ctxt;
- return memalign(alignment, size);
-}
-
-static void ivd_aligned_free(void *ctxt, void *mem) {
- (void) ctxt;
- free(mem);
-}
-
-C2SoftHevcDec::C2SoftHevcDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mDecHandle(nullptr),
- mOutBufferFlush(nullptr),
- mIvColorformat(IV_YUV_420P),
- mWidth(320),
- mHeight(240),
- mHeaderDecoded(false) {
-}
-
-C2SoftHevcDec::~C2SoftHevcDec() {
- onRelease();
-}
-
-c2_status_t C2SoftHevcDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftHevcDec::onStop() {
- if (OK != resetDecoder()) return C2_CORRUPTED;
- resetPlugin();
- return C2_OK;
-}
-
-void C2SoftHevcDec::onReset() {
- (void) onStop();
-}
-
-void C2SoftHevcDec::onRelease() {
- (void) deleteDecoder();
- if (mOutBufferFlush) {
- ivd_aligned_free(nullptr, mOutBufferFlush);
- mOutBufferFlush = nullptr;
- }
- if (mOutBlock) {
- mOutBlock.reset();
- }
-}
-
-c2_status_t C2SoftHevcDec::onFlush_sm() {
- if (OK != setFlushMode()) return C2_CORRUPTED;
-
- uint32_t displayStride = mStride;
- uint32_t displayHeight = mHeight;
- uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
- mOutBufferFlush = (uint8_t *)ivd_aligned_malloc(nullptr, 128, bufferSize);
- if (!mOutBufferFlush) {
- ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
- return C2_NO_MEMORY;
- }
-
- while (true) {
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
-
- setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- if (0 == s_decode_op.u4_output_present) {
- resetPlugin();
- break;
- }
- }
-
- if (mOutBufferFlush) {
- ivd_aligned_free(nullptr, mOutBufferFlush);
- mOutBufferFlush = nullptr;
- }
-
- return C2_OK;
-}
-
-status_t C2SoftHevcDec::createDecoder() {
- ivdext_create_ip_t s_create_ip;
- ivdext_create_op_t s_create_op;
-
- s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
- s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
- s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
- s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
- s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
- s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
- s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = nullptr;
- s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_create_ip,
- &s_create_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__,
- s_create_op.s_ivd_create_op_t.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mDecHandle = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
- mDecHandle->pv_fxns = (void *)ivdec_api_function;
- mDecHandle->u4_size = sizeof(iv_obj_t);
-
- return OK;
-}
-
-status_t C2SoftHevcDec::setNumCores() {
- ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
- ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
-
- s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
- s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
- s_set_num_cores_ip.u4_num_cores = mNumCores;
- s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_num_cores_ip,
- &s_set_num_cores_op);
- if (IV_SUCCESS != status) {
- ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftHevcDec::setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode) {
- ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
- ivd_ctl_set_config_op_t s_set_dyn_params_op;
-
- s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
- s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
- s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
- s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
- s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
- s_set_dyn_params_ip.e_vid_dec_mode = dec_mode;
- s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_dyn_params_ip,
- &s_set_dyn_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftHevcDec::getVersion() {
- ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
- ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
- UWORD8 au1_buf[512];
-
- s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
- s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
- s_get_versioninfo_ip.pv_version_buffer = au1_buf;
- s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
- s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_get_versioninfo_ip,
- &s_get_versioninfo_op);
- if (status != IV_SUCCESS) {
- ALOGD("error in %s: 0x%x", __func__,
- s_get_versioninfo_op.u4_error_code);
- } else {
- ALOGV("ittiam decoder version number: %s",
- (char *) s_get_versioninfo_ip.pv_version_buffer);
- }
-
- return OK;
-}
-
-status_t C2SoftHevcDec::initDecoder() {
- if (OK != createDecoder()) return UNKNOWN_ERROR;
- mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN64(mWidth);
- mSignalledError = false;
- resetPlugin();
- (void) setNumCores();
- if (OK != setParams(mStride, IVD_DECODE_FRAME)) return UNKNOWN_ERROR;
- (void) getVersion();
-
- return OK;
-}
-
-bool C2SoftHevcDec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
- ivd_video_decode_op_t *ps_decode_op,
- C2ReadView *inBuffer,
- C2GraphicView *outBuffer,
- size_t inOffset,
- size_t inSize,
- uint32_t tsMarker) {
- uint32_t displayStride = mStride;
- uint32_t displayHeight = mHeight;
- size_t lumaSize = displayStride * displayHeight;
- size_t chromaSize = lumaSize >> 2;
-
- ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
- ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
- if (inBuffer) {
- ps_decode_ip->u4_ts = tsMarker;
- ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
- ps_decode_ip->u4_num_Bytes = inSize;
- } else {
- ps_decode_ip->u4_ts = 0;
- ps_decode_ip->pv_stream_buffer = nullptr;
- ps_decode_ip->u4_num_Bytes = 0;
- }
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
- if (outBuffer) {
- if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
- ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
- outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
- return false;
- }
- ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
- ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
- ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
- } else {
- ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferFlush;
- ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferFlush + lumaSize;
- ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferFlush + lumaSize + chromaSize;
- }
- ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
- ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
- ps_decode_op->u4_output_present = 0;
-
- return true;
-}
-
-bool C2SoftHevcDec::getVuiParams() {
- ivdext_ctl_get_vui_params_ip_t s_get_vui_params_ip;
- ivdext_ctl_get_vui_params_op_t s_get_vui_params_op;
-
- s_get_vui_params_ip.u4_size = sizeof(ivdext_ctl_get_vui_params_ip_t);
- s_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_get_vui_params_ip.e_sub_cmd =
- (IVD_CONTROL_API_COMMAND_TYPE_T) IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS;
- s_get_vui_params_op.u4_size = sizeof(ivdext_ctl_get_vui_params_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_get_vui_params_ip,
- &s_get_vui_params_op);
- if (status != IV_SUCCESS) {
- ALOGD("error in %s: 0x%x", __func__, s_get_vui_params_op.u4_error_code);
- return false;
- }
-
- VuiColorAspects vuiColorAspects;
- vuiColorAspects.primaries = s_get_vui_params_op.u1_colour_primaries;
- vuiColorAspects.transfer = s_get_vui_params_op.u1_transfer_characteristics;
- vuiColorAspects.coeffs = s_get_vui_params_op.u1_matrix_coefficients;
- vuiColorAspects.fullRange = s_get_vui_params_op.u1_video_full_range_flag;
-
- // convert vui aspects to C2 values if changed
- if (!(vuiColorAspects == mBitstreamColorAspects)) {
- mBitstreamColorAspects = vuiColorAspects;
- ColorAspects sfAspects;
- C2StreamColorAspectsInfo::input codedAspects = { 0u };
- ColorUtils::convertIsoColorAspectsToCodecAspects(
- vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
- vuiColorAspects.fullRange, sfAspects);
- if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
- codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
- codedAspects.range = C2Color::RANGE_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
- codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
- codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
- }
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
- }
- return true;
-}
-
-status_t C2SoftHevcDec::setFlushMode() {
- ivd_ctl_flush_ip_t s_set_flush_ip;
- ivd_ctl_flush_op_t s_set_flush_op;
-
- s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
- s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
- s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_flush_ip,
- &s_set_flush_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftHevcDec::resetDecoder() {
- ivd_ctl_reset_ip_t s_reset_ip;
- ivd_ctl_reset_op_t s_reset_op;
-
- s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
- s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
- s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_reset_ip,
- &s_reset_op);
- if (IV_SUCCESS != status) {
- ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mStride = 0;
- (void) setNumCores();
- mSignalledError = false;
- mHeaderDecoded = false;
- return OK;
-}
-
-void C2SoftHevcDec::resetPlugin() {
- mSignalledOutputEos = false;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
-}
-
-status_t C2SoftHevcDec::deleteDecoder() {
- if (mDecHandle) {
- ivdext_delete_ip_t s_delete_ip;
- ivdext_delete_op_t s_delete_op;
-
- s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ivdext_delete_ip_t);
- s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
- s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ivdext_delete_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_delete_ip,
- &s_delete_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__,
- s_delete_op.s_ivd_delete_op_t.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mDecHandle = nullptr;
- }
-
- return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftHevcDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
- std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
- C2Rect(mWidth, mHeight));
- mOutBlock = nullptr;
- {
- IntfImpl::Lock lock = mIntf->lock();
- buffer->setInfo(mIntf->getColorAspects_l());
- }
-
- auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
- fillWork(work);
- } else {
- finish(index, fillWork);
- }
-}
-
-c2_status_t C2SoftHevcDec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
- if (!mDecHandle) {
- ALOGE("not supposed to be here, invalid decoder context");
- return C2_CORRUPTED;
- }
- if (mStride != ALIGN64(mWidth)) {
- mStride = ALIGN64(mWidth);
- if (OK != setParams(mStride, IVD_DECODE_FRAME)) return C2_CORRUPTED;
- }
- if (mOutBlock &&
- (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
- mOutBlock.reset();
- }
- if (!mOutBlock) {
- uint32_t format = HAL_PIXEL_FORMAT_YV12;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return err;
- }
- ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
- }
-
- return C2_OK;
-}
-
-// TODO: can overall error checking be improved?
-// TODO: allow configuration of color format and usage for graphic buffers instead
-// of hard coding them to HAL_PIXEL_FORMAT_YV12
-// TODO: pass coloraspects information to surface
-// TODO: test support for dynamic change in resolution
-// TODO: verify if the decoder sent back all frames
-void C2SoftHevcDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 0u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- size_t inOffset = 0u;
- size_t inSize = 0u;
- uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- bool hasPicture = false;
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
- size_t inPos = 0;
- while (inPos < inSize) {
- if (C2_OK != ensureDecoderState(pool)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
- if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
- inOffset + inPos, inSize - inPos, workIndex)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
-
- if (false == mHeaderDecoded) {
- /* Decode header and get dimensions */
- setParams(mStride, IVD_DECODE_HEADER);
- }
- WORD32 delay;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- WORD32 decodeTime;
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
- s_decode_op.u4_num_bytes_consumed);
- if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGE("allocation failure in decoder");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGV("resolution changed");
- drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
- resetDecoder();
- resetPlugin();
- work->workletsProcessed = 0u;
-
- /* Decode header and get new dimensions */
- setParams(mStride, IVD_DECODE_HEADER);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- }
- if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
- if (mHeaderDecoded == false) {
- mHeaderDecoded = true;
- setParams(ALIGN64(s_decode_op.u4_pic_wd), IVD_DECODE_FRAME);
- }
- if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
- mWidth = s_decode_op.u4_pic_wd;
- mHeight = s_decode_op.u4_pic_ht;
- CHECK_EQ(0u, s_decode_op.u4_output_present);
-
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err =
- mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- } else {
- ALOGE("Cannot set width and height");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- continue;
- }
- }
- (void) getVuiParams();
- hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
- if (s_decode_op.u4_output_present) {
- finishWork(s_decode_op.u4_ts, work);
- }
- if (0 == s_decode_op.u4_num_bytes_consumed) {
- ALOGD("Bytes consumed is zero. Ignoring remaining bytes");
- break;
- }
- inPos += s_decode_op.u4_num_bytes_consumed;
- if (hasPicture && (inSize - inPos)) {
- ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
- (int)inSize - (int)inPos);
- break;
- }
- }
-
- if (eos) {
- drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
- mSignalledOutputEos = true;
- } else if (!hasPicture) {
- fillEmptyWork(work);
- }
-}
-
-c2_status_t C2SoftHevcDec::drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work) {
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- if (OK != setFlushMode()) return C2_CORRUPTED;
- while (true) {
- if (C2_OK != ensureDecoderState(pool)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return C2_CORRUPTED;
- }
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- return C2_CORRUPTED;
- }
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
- if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- return C2_CORRUPTED;
- }
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- if (s_decode_op.u4_output_present) {
- finishWork(s_decode_op.u4_ts, work);
- } else {
- fillEmptyWork(work);
- break;
- }
- }
-
- return C2_OK;
-}
-
-c2_status_t C2SoftHevcDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftHevcDecFactory : public C2ComponentFactory {
-public:
- C2SoftHevcDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftHevcDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftHevcDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftHevcDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftHevcDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftHevcDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftHevcDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/hevc/C2SoftHevcDec.h b/media/codecs/hevc/C2SoftHevcDec.h
deleted file mode 100644
index 75111fc..0000000
--- a/media/codecs/hevc/C2SoftHevcDec.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_HEVC_DEC_H_
-#define ANDROID_C2_SOFT_HEVC_DEC_H_
-
-#include <media/stagefright/foundation/ColorUtils.h>
-
-#include <SimpleC2Component.h>
-
-#include "ihevc_typedefs.h"
-#include "iv.h"
-#include "ivd.h"
-
-namespace android {
-
-#define ivdec_api_function ihevcd_cxa_api_function
-#define ivdext_create_ip_t ihevcd_cxa_create_ip_t
-#define ivdext_create_op_t ihevcd_cxa_create_op_t
-#define ivdext_delete_ip_t ihevcd_cxa_delete_ip_t
-#define ivdext_delete_op_t ihevcd_cxa_delete_op_t
-#define ivdext_ctl_set_num_cores_ip_t ihevcd_cxa_ctl_set_num_cores_ip_t
-#define ivdext_ctl_set_num_cores_op_t ihevcd_cxa_ctl_set_num_cores_op_t
-#define ivdext_ctl_get_vui_params_ip_t ihevcd_cxa_ctl_get_vui_params_ip_t
-#define ivdext_ctl_get_vui_params_op_t ihevcd_cxa_ctl_get_vui_params_op_t
-#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
-#define MAX_NUM_CORES 4
-#define IVDEXT_CMD_CTL_SET_NUM_CORES \
- (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
-
-struct C2SoftHevcDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftHevcDec(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftHevcDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
- private:
- status_t createDecoder();
- status_t setNumCores();
- status_t setParams(size_t stride, IVD_VIDEO_DECODE_MODE_T dec_mode);
- status_t getVersion();
- status_t initDecoder();
- bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
- ivd_video_decode_op_t *ps_decode_op,
- C2ReadView *inBuffer,
- C2GraphicView *outBuffer,
- size_t inOffset,
- size_t inSize,
- uint32_t tsMarker);
- bool getVuiParams();
- // TODO:This is not the right place for colorAspects functions. These should
- // be part of c2-vndk so that they can be accessed by all video plugins
- // until then, make them feel at home
- bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
- void updateFinalColorAspects(
- const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
- status_t handleColorAspectsChange();
- c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
- void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
- status_t setFlushMode();
- c2_status_t drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work);
- status_t resetDecoder();
- void resetPlugin();
- status_t deleteDecoder();
-
- // TODO:This is not the right place for this enum. These should
- // be part of c2-vndk so that they can be accessed by all video plugins
- // until then, make them feel at home
- enum {
- kNotSupported,
- kPreferBitstream,
- kPreferContainer,
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- iv_obj_t *mDecHandle;
- std::shared_ptr<C2GraphicBlock> mOutBlock;
- uint8_t *mOutBufferFlush;
-
- size_t mNumCores;
- IV_COLOR_FORMAT_T mIvColorformat;
-
- uint32_t mWidth;
- uint32_t mHeight;
- uint32_t mStride;
- bool mSignalledOutputEos;
- bool mSignalledError;
- bool mHeaderDecoded;
-
- // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
- // converting them to C2 values for each frame
- struct VuiColorAspects {
- uint8_t primaries;
- uint8_t transfer;
- uint8_t coeffs;
- uint8_t fullRange;
-
- // default color aspects
- VuiColorAspects()
- : primaries(2), transfer(2), coeffs(2), fullRange(0) { }
-
- bool operator==(const VuiColorAspects &o) {
- return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
- && fullRange == o.fullRange;
- }
- } mBitstreamColorAspects;
-
- // profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
-
- C2_DO_NOT_COPY(C2SoftHevcDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_HEVC_DEC_H_
diff --git a/media/codecs/mp3/Android.bp b/media/codecs/mp3/Android.bp
deleted file mode 100644
index 6e013b8..0000000
--- a/media/codecs/mp3/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2mp3dec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftMp3Dec.cpp"],
-
- static_libs: ["libstagefright_mp3dec"],
-}
diff --git a/media/codecs/mp3/C2SoftMp3Dec.cpp b/media/codecs/mp3/C2SoftMp3Dec.cpp
deleted file mode 100644
index c8b8397..0000000
--- a/media/codecs/mp3/C2SoftMp3Dec.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftMp3Dec"
-#include <log/log.h>
-
-#include <numeric>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftMp3Dec.h"
-#include "pvmp3decoder_api.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.mp3.decoder";
-
-class C2SoftMP3::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_MPEG))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).oneOf({8000, 11025, 12000, 16000,
- 22050, 24000, 32000, 44100, 48000})})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 2))
- .withFields({C2F(mChannelCount, value).inRange(1, 2)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(8000, 320000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftMP3::C2SoftMP3(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mConfig(nullptr),
- mDecoderBuf(nullptr) {
-}
-
-C2SoftMP3::~C2SoftMP3() {
- onRelease();
-}
-
-c2_status_t C2SoftMP3::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftMP3::onStop() {
- // Make sure that the next buffer output does not still
- // depend on fragments from the last one decoded.
- pvmp3_InitDecoder(mConfig, mDecoderBuf);
- mSignalledError = false;
- mIsFirst = true;
- mSignalledOutputEos = false;
- mAnchorTimeStamp = 0;
- mProcessedSamples = 0;
-
- return C2_OK;
-}
-
-void C2SoftMP3::onReset() {
- (void)onStop();
-}
-
-void C2SoftMP3::onRelease() {
- mGaplessBytes = false;
- if (mDecoderBuf) {
- free(mDecoderBuf);
- mDecoderBuf = nullptr;
- }
-
- if (mConfig) {
- delete mConfig;
- mConfig = nullptr;
- }
-}
-
-status_t C2SoftMP3::initDecoder() {
- mConfig = new tPVMP3DecoderExternal{};
- if (!mConfig) return NO_MEMORY;
- mConfig->equalizerType = flat;
- mConfig->crcEnabled = false;
-
- size_t memRequirements = pvmp3_decoderMemRequirements();
- mDecoderBuf = malloc(memRequirements);
- if (!mDecoderBuf) return NO_MEMORY;
-
- pvmp3_InitDecoder(mConfig, mDecoderBuf);
-
- mIsFirst = true;
- mGaplessBytes = false;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mAnchorTimeStamp = 0;
- mProcessedSamples = 0;
-
- return OK;
-}
-
-/* The below code is borrowed from ./test/mp3reader.cpp */
-static bool parseMp3Header(uint32_t header, size_t *frame_size,
- uint32_t *out_sampling_rate = nullptr,
- uint32_t *out_channels = nullptr,
- uint32_t *out_bitrate = nullptr,
- uint32_t *out_num_samples = nullptr) {
- *frame_size = 0;
- if (out_sampling_rate) *out_sampling_rate = 0;
- if (out_channels) *out_channels = 0;
- if (out_bitrate) *out_bitrate = 0;
- if (out_num_samples) *out_num_samples = 1152;
-
- if ((header & 0xffe00000) != 0xffe00000) return false;
-
- unsigned version = (header >> 19) & 3;
- if (version == 0x01) return false;
-
- unsigned layer = (header >> 17) & 3;
- if (layer == 0x00) return false;
-
- unsigned bitrate_index = (header >> 12) & 0x0f;
- if (bitrate_index == 0 || bitrate_index == 0x0f) return false;
-
- unsigned sampling_rate_index = (header >> 10) & 3;
- if (sampling_rate_index == 3) return false;
-
- static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
- int sampling_rate = kSamplingRateV1[sampling_rate_index];
- if (version == 2 /* V2 */) {
- sampling_rate /= 2;
- } else if (version == 0 /* V2.5 */) {
- sampling_rate /= 4;
- }
-
- unsigned padding = (header >> 9) & 1;
-
- if (layer == 3) { // layer I
- static const int kBitrateV1[] =
- {
- 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
- };
- static const int kBitrateV2[] =
- {
- 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256
- };
-
- int bitrate = (version == 3 /* V1 */) ? kBitrateV1[bitrate_index - 1] :
- kBitrateV2[bitrate_index - 1];
-
- if (out_bitrate) {
- *out_bitrate = bitrate;
- }
- *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
- if (out_num_samples) {
- *out_num_samples = 384;
- }
- } else { // layer II or III
- static const int kBitrateV1L2[] =
- {
- 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
- };
-
- static const int kBitrateV1L3[] =
- {
- 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320
- };
-
- static const int kBitrateV2[] =
- {
- 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
- };
-
- int bitrate;
- if (version == 3 /* V1 */) {
- bitrate = (layer == 2 /* L2 */) ? kBitrateV1L2[bitrate_index - 1] :
- kBitrateV1L3[bitrate_index - 1];
-
- if (out_num_samples) {
- *out_num_samples = 1152;
- }
- } else { // V2 (or 2.5)
- bitrate = kBitrateV2[bitrate_index - 1];
- if (out_num_samples) {
- *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
- }
- }
-
- if (out_bitrate) {
- *out_bitrate = bitrate;
- }
-
- if (version == 3 /* V1 */) {
- *frame_size = 144000 * bitrate / sampling_rate + padding;
- } else { // V2 or V2.5
- size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
- *frame_size = tmp * bitrate / sampling_rate + padding;
- }
- }
-
- if (out_sampling_rate) {
- *out_sampling_rate = sampling_rate;
- }
-
- if (out_channels) {
- int channel_mode = (header >> 6) & 3;
-
- *out_channels = (channel_mode == 3) ? 1 : 2;
- }
-
- return true;
-}
-
-static uint32_t U32_AT(const uint8_t *ptr) {
- return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
-}
-
-static status_t calculateOutSize(uint8 *header, size_t inSize,
- std::vector<size_t> *decodedSizes) {
- uint32_t channels;
- uint32_t numSamples;
- size_t frameSize;
- size_t totalInSize = 0;
-
- while (totalInSize + 4 < inSize) {
- if (!parseMp3Header(U32_AT(header + totalInSize), &frameSize,
- nullptr, &channels, nullptr, &numSamples)) {
- ALOGE("Error in parse mp3 header during outSize estimation");
- return UNKNOWN_ERROR;
- }
- totalInSize += frameSize;
- decodedSizes->push_back(numSamples * channels * sizeof(int16_t));
- }
-
- if (decodedSizes->empty()) return UNKNOWN_ERROR;
-
- return OK;
-}
-
-c2_status_t C2SoftMP3::onFlush_sm() {
- return onStop();
-}
-
-c2_status_t C2SoftMP3::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-// TODO: Can overall error checking be improved? As in the check for validity of
-// work, pool ptr, work->input.buffers.size() == 1, ...
-// TODO: Blind removal of 529 samples from the output may not work. Because
-// mpeg layer 1 frame size is 384 samples per frame. This should introduce
-// negative values and can cause SEG faults. Soft omx mp3 plugin can have
-// this problem (CHECK!)
-void C2SoftMP3::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- size_t inSize = 0u;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
-
- if (inSize == 0 && (!mGaplessBytes || !eos)) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- return;
- }
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
- int32_t numChannels = mConfig->num_channels;
- size_t calOutSize;
- std::vector<size_t> decodedSizes;
- if (inSize && OK != calculateOutSize(const_cast<uint8 *>(rView.data()),
- inSize, &decodedSizes)) {
- work->result = C2_CORRUPTED;
- return;
- }
- calOutSize = std::accumulate(decodedSizes.begin(), decodedSizes.end(), 0);
- if (eos) {
- calOutSize += kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
- }
-
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(calOutSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
-
- int outSize = 0;
- int outOffset = 0;
- auto it = decodedSizes.begin();
- size_t inPos = 0;
- int32_t samplingRate = mConfig->samplingRate;
- while (inPos < inSize) {
- if (it == decodedSizes.end()) {
- ALOGE("unexpected trailing bytes, ignoring them");
- break;
- }
-
- mConfig->pInputBuffer = const_cast<uint8 *>(rView.data() + inPos);
- mConfig->inputBufferCurrentLength = (inSize - inPos);
- mConfig->inputBufferMaxLength = 0;
- mConfig->inputBufferUsedLength = 0;
- mConfig->outputFrameSize = (calOutSize - outSize);
- mConfig->pOutputBuffer = reinterpret_cast<int16_t *> (wView.data() + outSize);
-
- ERROR_CODE decoderErr;
- if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
- != NO_DECODING_ERROR) {
- ALOGE("mp3 decoder returned error %d", decoderErr);
- if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
- && decoderErr != SIDE_INFO_ERROR) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- // This is recoverable, just ignore the current frame and
- // play silence instead.
- ALOGV("ignoring error and sending silence");
- if (mConfig->outputFrameSize == 0) {
- mConfig->outputFrameSize = *it / sizeof(int16_t);
- }
- memset(mConfig->pOutputBuffer, 0, mConfig->outputFrameSize * sizeof(int16_t));
- } else if (mConfig->samplingRate != samplingRate
- || mConfig->num_channels != numChannels) {
- ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
- samplingRate, mConfig->samplingRate,
- numChannels, mConfig->num_channels);
- samplingRate = mConfig->samplingRate;
- numChannels = mConfig->num_channels;
-
- C2StreamSampleRateInfo::output sampleRateInfo(0u, samplingRate);
- C2StreamChannelCountInfo::output channelCountInfo(0u, numChannels);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config(
- { &sampleRateInfo, &channelCountInfo },
- C2_MAY_BLOCK,
- &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
- } else {
- ALOGE("Config Update failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- if (*it != mConfig->outputFrameSize * sizeof(int16_t)) {
- ALOGE("panic, parsed size does not match decoded size");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- outSize += mConfig->outputFrameSize * sizeof(int16_t);
- inPos += mConfig->inputBufferUsedLength;
- it++;
- }
- if (mIsFirst) {
- mIsFirst = false;
- mGaplessBytes = true;
- // The decoder delay is 529 samples, so trim that many samples off
- // the start of the first output buffer. This essentially makes this
- // decoder have zero delay, which the rest of the pipeline assumes.
- outOffset = kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
- mAnchorTimeStamp = work->input.ordinal.timestamp.peekull();
- }
- if (eos) {
- if (calOutSize >=
- outSize + kPVMP3DecoderDelay * numChannels * sizeof(int16_t)) {
- if (!memset(reinterpret_cast<int16_t*>(wView.data() + outSize), 0,
- kPVMP3DecoderDelay * numChannels * sizeof(int16_t))) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- ALOGV("Adding 529 samples at end");
- mGaplessBytes = false;
- outSize += kPVMP3DecoderDelay * numChannels * sizeof(int16_t);
- }
- }
-
- uint64_t outTimeStamp = mProcessedSamples * 1000000ll / samplingRate;
- mProcessedSamples += ((outSize - outOffset) / (numChannels * sizeof(int16_t)));
- ALOGV("out buffer attr. offset %d size %d timestamp %u", outOffset, outSize - outOffset,
- (uint32_t)(mAnchorTimeStamp + outTimeStamp));
- decodedSizes.clear();
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(
- createLinearBuffer(block, outOffset, outSize - outOffset));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->worklets.front()->output.ordinal.timestamp = mAnchorTimeStamp + outTimeStamp;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-class C2SoftMp3DecFactory : public C2ComponentFactory {
-public:
- C2SoftMp3DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftMP3(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftMP3::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftMP3::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftMP3::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftMp3DecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftMp3DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
-
diff --git a/media/codecs/mp3/C2SoftMp3Dec.h b/media/codecs/mp3/C2SoftMp3Dec.h
deleted file mode 100644
index 402bdc4..0000000
--- a/media/codecs/mp3/C2SoftMp3Dec.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_MP3_DEC_H_
-#define ANDROID_C2_SOFT_MP3_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-struct tPVMP3DecoderExternal;
-
-bool parseMp3Header(uint32_t header, size_t *frame_size,
- uint32_t *out_sampling_rate = nullptr,
- uint32_t *out_channels = nullptr,
- uint32_t *out_bitrate = nullptr,
- uint32_t *out_num_samples = nullptr);
-
-namespace android {
-
-struct C2SoftMP3 : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftMP3(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftMP3();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- enum {
- kPVMP3DecoderDelay = 529 // samples
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- tPVMP3DecoderExternal *mConfig;
- void *mDecoderBuf;
-
- bool mIsFirst;
- bool mSignalledError;
- bool mSignalledOutputEos;
- bool mGaplessBytes;
- uint64_t mAnchorTimeStamp;
- uint64_t mProcessedSamples;
-
- status_t initDecoder();
-
- C2_DO_NOT_COPY(C2SoftMP3);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_MP3_DEC_H_
diff --git a/media/codecs/mp3/MODULE_LICENSE_APACHE2 b/media/codecs/mp3/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/mp3/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/mp3/NOTICE b/media/codecs/mp3/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/mp3/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/mp3/patent_disclaimer.txt b/media/codecs/mp3/patent_disclaimer.txt
deleted file mode 100644
index b4bf11d..0000000
--- a/media/codecs/mp3/patent_disclaimer.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-THIS IS NOT A GRANT OF PATENT RIGHTS.
-
-Google makes no representation or warranty that the codecs for which
-source code is made available hereunder are unencumbered by
-third-party patents. Those intending to use this source code in
-hardware or software products are advised that implementations of
-these codecs, including in open source software or shareware, may
-require patent licenses from the relevant patent holders.
diff --git a/media/codecs/mpeg2/Android.bp b/media/codecs/mpeg2/Android.bp
deleted file mode 100644
index 85d867e..0000000
--- a/media/codecs/mpeg2/Android.bp
+++ /dev/null
@@ -1,16 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2mpeg2dec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- srcs: ["C2SoftMpeg2Dec.cpp"],
-
- static_libs: ["libmpeg2dec"],
-
- include_dirs: [
- "external/libmpeg2/decoder",
- "external/libmpeg2/common",
- ],
-}
diff --git a/media/codecs/mpeg2/C2SoftMpeg2Dec.cpp b/media/codecs/mpeg2/C2SoftMpeg2Dec.cpp
deleted file mode 100644
index da32ec0..0000000
--- a/media/codecs/mpeg2/C2SoftMpeg2Dec.cpp
+++ /dev/null
@@ -1,1069 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftMpeg2Dec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <Codec2Mapper.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftMpeg2Dec.h"
-#include "impeg2d.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.mpeg2.decoder";
-
-class C2SoftMpeg2Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : SimpleInterface<void>::BaseParams(
- helper,
- COMPONENT_NAME,
- C2Component::KIND_DECODER,
- C2Component::DOMAIN_VIDEO,
- MEDIA_MIMETYPE_VIDEO_MPEG2) {
- noPrivateBuffers(); // TODO: account for our buffers here
- noInputReferences();
- noOutputReferences();
- noInputLatency();
- noTimeStretch();
-
- // TODO: output latency and reordering
-
- addParameter(
- DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
- .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(16, 1920, 4),
- C2F(mSize, height).inRange(16, 1088, 4),
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_MP2V_SIMPLE, C2Config::LEVEL_MP2V_HIGH))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_MP2V_SIMPLE,
- C2Config::PROFILE_MP2V_MAIN}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_MP2V_LOW,
- C2Config::LEVEL_MP2V_MAIN,
- C2Config::LEVEL_MP2V_HIGH_1440,
- C2Config::LEVEL_MP2V_HIGH})
- })
- .withSetter(ProfileLevelSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
- .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 1920, 2),
- C2F(mSize, height).inRange(2, 1088, 2),
- })
- .withSetter(MaxPictureSizeSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 2))
- .withFields({
- C2F(mMaxInputSize, value).any(),
- })
- .calculatedAs(MaxInputSizeSetter, mMaxSize)
- .build());
-
- C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
- std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- 1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
- memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
-
- defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- { C2ChromaOffsetStruct::ITU_YUV_420_0() },
- 0u, 8u /* bitDepth */, C2Color::YUV_420);
- helper->addStructDescriptors<C2ChromaOffsetStruct>();
-
- addParameter(
- DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
- .withConstValue(defaultColorInfo)
- .build());
-
- addParameter(
- DefineParam(mDefaultColorAspects, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsTuning::output(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mDefaultColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mDefaultColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mDefaultColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mDefaultColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(DefaultColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::input(
- 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mCodedColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mCodedColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mCodedColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mCodedColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(CodedColorAspectsSetter)
- .build());
-
- addParameter(
- DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS)
- .withDefault(new C2StreamColorAspectsInfo::output(
- 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED,
- C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED))
- .withFields({
- C2F(mColorAspects, range).inRange(
- C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER),
- C2F(mColorAspects, primaries).inRange(
- C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER),
- C2F(mColorAspects, transfer).inRange(
- C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER),
- C2F(mColorAspects, matrix).inRange(
- C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)
- })
- .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects)
- .build());
-
- // TODO: support more formats?
- addParameter(
- DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
- .build());
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
- C2P<C2VideoSizeStreamInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- // TODO: get max width/height from the size's field helpers vs. hardcoding
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 1920u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 1088u);
- return C2R::Ok();
- }
-
- static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
- const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
- (void)mayBlock;
- // assume compression ratio of 1
- me.set().value = (((maxSize.v.width + 15) / 16) * ((maxSize.v.height + 15) / 16) * 384);
- return C2R::Ok();
- }
-
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- (void)size;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- static C2R DefaultColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsTuning::output> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
- }
-
- static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) {
- (void)mayBlock;
- if (me.v.range > C2Color::RANGE_OTHER) {
- me.set().range = C2Color::RANGE_OTHER;
- }
- if (me.v.primaries > C2Color::PRIMARIES_OTHER) {
- me.set().primaries = C2Color::PRIMARIES_OTHER;
- }
- if (me.v.transfer > C2Color::TRANSFER_OTHER) {
- me.set().transfer = C2Color::TRANSFER_OTHER;
- }
- if (me.v.matrix > C2Color::MATRIX_OTHER) {
- me.set().matrix = C2Color::MATRIX_OTHER;
- }
- return C2R::Ok();
- }
-
- static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
- const C2P<C2StreamColorAspectsTuning::output> &def,
- const C2P<C2StreamColorAspectsInfo::input> &coded) {
- (void)mayBlock;
- // take default values for all unspecified fields, and coded values for specified ones
- me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
- me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
- ? def.v.primaries : coded.v.primaries;
- me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED
- ? def.v.transfer : coded.v.transfer;
- me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix;
- return C2R::Ok();
- }
-
- std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() {
- return mColorAspects;
- }
-
-private:
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
- std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
- std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
- std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects;
- std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
- std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
- std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
-};
-
-static size_t getCpuCoreCount() {
- long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
- cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- // _SC_NPROC_ONLN must be defined...
- cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
- CHECK(cpuCoreCount >= 1);
- ALOGV("Number of CPU cores: %ld", cpuCoreCount);
- return (size_t)cpuCoreCount;
-}
-
-static void *ivd_aligned_malloc(WORD32 alignment, WORD32 size) {
- return memalign(alignment, size);
-}
-
-static void ivd_aligned_free(void *mem) {
- free(mem);
-}
-
-C2SoftMpeg2Dec::C2SoftMpeg2Dec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mDecHandle(nullptr),
- mMemRecords(nullptr),
- mOutBufferDrain(nullptr),
- mIvColorformat(IV_YUV_420P),
- mWidth(320),
- mHeight(240) {
- // If input dump is enabled, then open create an empty file
- GENERATE_FILE_NAMES();
- CREATE_DUMP_FILE(mInFile);
-}
-
-C2SoftMpeg2Dec::~C2SoftMpeg2Dec() {
- onRelease();
-}
-
-c2_status_t C2SoftMpeg2Dec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftMpeg2Dec::onStop() {
- if (OK != resetDecoder()) return C2_CORRUPTED;
- resetPlugin();
- return C2_OK;
-}
-
-void C2SoftMpeg2Dec::onReset() {
- (void) onStop();
-}
-
-void C2SoftMpeg2Dec::onRelease() {
- (void) deleteDecoder();
- if (mOutBufferDrain) {
- ivd_aligned_free(mOutBufferDrain);
- mOutBufferDrain = nullptr;
- }
- if (mOutBlock) {
- mOutBlock.reset();
- }
- if (mMemRecords) {
- ivd_aligned_free(mMemRecords);
- mMemRecords = nullptr;
- }
-}
-
-c2_status_t C2SoftMpeg2Dec::onFlush_sm() {
- if (OK != setFlushMode()) return C2_CORRUPTED;
-
- uint32_t displayStride = mStride;
- uint32_t displayHeight = mHeight;
- uint32_t bufferSize = displayStride * displayHeight * 3 / 2;
- mOutBufferDrain = (uint8_t *)ivd_aligned_malloc(128, bufferSize);
- if (!mOutBufferDrain) {
- ALOGE("could not allocate tmp output buffer (for flush) of size %u ", bufferSize);
- return C2_NO_MEMORY;
- }
-
- while (true) {
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
-
- setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, nullptr, 0, 0, 0);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- if (0 == s_decode_op.u4_output_present) {
- resetPlugin();
- break;
- }
- }
-
- if (mOutBufferDrain) {
- ivd_aligned_free(mOutBufferDrain);
- mOutBufferDrain = nullptr;
- }
-
- return C2_OK;
-}
-
-status_t C2SoftMpeg2Dec::getNumMemRecords() {
- iv_num_mem_rec_ip_t s_num_mem_rec_ip;
- iv_num_mem_rec_op_t s_num_mem_rec_op;
-
- s_num_mem_rec_ip.u4_size = sizeof(s_num_mem_rec_ip);
- s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
- s_num_mem_rec_op.u4_size = sizeof(s_num_mem_rec_op);
-
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_num_mem_rec_ip,
- &s_num_mem_rec_op);
- if (IV_SUCCESS != status) {
- ALOGE("Error in getting mem records: 0x%x", s_num_mem_rec_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
- mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::fillMemRecords() {
- iv_mem_rec_t *ps_mem_rec = (iv_mem_rec_t *) ivd_aligned_malloc(
- 128, mNumMemRecords * sizeof(iv_mem_rec_t));
- if (!ps_mem_rec) {
- ALOGE("Allocation failure");
- return NO_MEMORY;
- }
- memset(ps_mem_rec, 0, mNumMemRecords * sizeof(iv_mem_rec_t));
- for (size_t i = 0; i < mNumMemRecords; i++)
- ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
- mMemRecords = ps_mem_rec;
-
- ivdext_fill_mem_rec_ip_t s_fill_mem_ip;
- ivdext_fill_mem_rec_op_t s_fill_mem_op;
-
- s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(ivdext_fill_mem_rec_ip_t);
- s_fill_mem_ip.u4_share_disp_buf = 0;
- s_fill_mem_ip.e_output_format = mIvColorformat;
- s_fill_mem_ip.u4_deinterlace = 1;
- s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
- s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords;
- s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = mWidth;
- s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = mHeight;
- s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(ivdext_fill_mem_rec_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_fill_mem_ip,
- &s_fill_mem_op);
- if (IV_SUCCESS != status) {
- ALOGE("Error in filling mem records: 0x%x",
- s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- CHECK_EQ(mNumMemRecords, s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
- for (size_t i = 0; i < mNumMemRecords; i++, ps_mem_rec++) {
- ps_mem_rec->pv_base = ivd_aligned_malloc(
- ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
- if (!ps_mem_rec->pv_base) {
- ALOGE("Allocation failure for memory record #%zu of size %u",
- i, ps_mem_rec->u4_mem_size);
- return NO_MEMORY;
- }
- }
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::createDecoder() {
- ivdext_init_ip_t s_init_ip;
- ivdext_init_op_t s_init_op;
-
- s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t);
- s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
- s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords;
- s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = mWidth;
- s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = mHeight;
- s_init_ip.u4_share_disp_buf = 0;
- s_init_ip.u4_deinterlace = 1;
- s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords;
- s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorformat;
- s_init_op.s_ivd_init_op_t.u4_size = sizeof(ivdext_init_op_t);
-
- mDecHandle = (iv_obj_t *)mMemRecords[0].pv_base;
- mDecHandle->pv_fxns = (void *)ivdec_api_function;
- mDecHandle->u4_size = sizeof(iv_obj_t);
-
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_init_ip,
- &s_init_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__,
- s_init_op.s_ivd_init_op_t.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::setNumCores() {
- ivdext_ctl_set_num_cores_ip_t s_set_num_cores_ip;
- ivdext_ctl_set_num_cores_op_t s_set_num_cores_op;
-
- s_set_num_cores_ip.u4_size = sizeof(ivdext_ctl_set_num_cores_ip_t);
- s_set_num_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_num_cores_ip.e_sub_cmd = IVDEXT_CMD_CTL_SET_NUM_CORES;
- s_set_num_cores_ip.u4_num_cores = mNumCores;
- s_set_num_cores_op.u4_size = sizeof(ivdext_ctl_set_num_cores_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_num_cores_ip,
- &s_set_num_cores_op);
- if (status != IV_SUCCESS) {
- ALOGD("error in %s: 0x%x", __func__, s_set_num_cores_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::setParams(size_t stride) {
- ivd_ctl_set_config_ip_t s_set_dyn_params_ip;
- ivd_ctl_set_config_op_t s_set_dyn_params_op;
-
- s_set_dyn_params_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
- s_set_dyn_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_dyn_params_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
- s_set_dyn_params_ip.u4_disp_wd = (UWORD32) stride;
- s_set_dyn_params_ip.e_frm_skip_mode = IVD_SKIP_NONE;
- s_set_dyn_params_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
- s_set_dyn_params_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
- s_set_dyn_params_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_dyn_params_ip,
- &s_set_dyn_params_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__, s_set_dyn_params_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::getVersion() {
- ivd_ctl_getversioninfo_ip_t s_get_versioninfo_ip;
- ivd_ctl_getversioninfo_op_t s_get_versioninfo_op;
- UWORD8 au1_buf[512];
-
- s_get_versioninfo_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
- s_get_versioninfo_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_get_versioninfo_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
- s_get_versioninfo_ip.pv_version_buffer = au1_buf;
- s_get_versioninfo_ip.u4_version_buffer_size = sizeof(au1_buf);
- s_get_versioninfo_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_get_versioninfo_ip,
- &s_get_versioninfo_op);
- if (status != IV_SUCCESS) {
- ALOGD("error in %s: 0x%x", __func__,
- s_get_versioninfo_op.u4_error_code);
- } else {
- ALOGV("ittiam decoder version number: %s",
- (char *) s_get_versioninfo_ip.pv_version_buffer);
- }
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::initDecoder() {
- status_t ret = getNumMemRecords();
- if (OK != ret) return ret;
-
- ret = fillMemRecords();
- if (OK != ret) return ret;
-
- if (OK != createDecoder()) return UNKNOWN_ERROR;
-
- mNumCores = MIN(getCpuCoreCount(), MAX_NUM_CORES);
- mStride = ALIGN64(mWidth);
- mSignalledError = false;
- resetPlugin();
- (void) setNumCores();
- if (OK != setParams(mStride)) return UNKNOWN_ERROR;
- (void) getVersion();
-
- return OK;
-}
-
-bool C2SoftMpeg2Dec::setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
- ivd_video_decode_op_t *ps_decode_op,
- C2ReadView *inBuffer,
- C2GraphicView *outBuffer,
- size_t inOffset,
- size_t inSize,
- uint32_t tsMarker) {
- uint32_t displayStride = mStride;
- uint32_t displayHeight = mHeight;
- size_t lumaSize = displayStride * displayHeight;
- size_t chromaSize = lumaSize >> 2;
-
- ps_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
- ps_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
- if (inBuffer) {
- ps_decode_ip->u4_ts = tsMarker;
- ps_decode_ip->pv_stream_buffer = const_cast<uint8_t *>(inBuffer->data() + inOffset);
- ps_decode_ip->u4_num_Bytes = inSize;
- } else {
- ps_decode_ip->u4_ts = 0;
- ps_decode_ip->pv_stream_buffer = nullptr;
- ps_decode_ip->u4_num_Bytes = 0;
- }
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = lumaSize;
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = chromaSize;
- ps_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = chromaSize;
- if (outBuffer) {
- if (outBuffer->width() < displayStride || outBuffer->height() < displayHeight) {
- ALOGE("Output buffer too small: provided (%dx%d) required (%ux%u)",
- outBuffer->width(), outBuffer->height(), displayStride, displayHeight);
- return false;
- }
- ps_decode_ip->s_out_buffer.pu1_bufs[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
- ps_decode_ip->s_out_buffer.pu1_bufs[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
- ps_decode_ip->s_out_buffer.pu1_bufs[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
- } else {
- ps_decode_ip->s_out_buffer.pu1_bufs[0] = mOutBufferDrain;
- ps_decode_ip->s_out_buffer.pu1_bufs[1] = mOutBufferDrain + lumaSize;
- ps_decode_ip->s_out_buffer.pu1_bufs[2] = mOutBufferDrain + lumaSize + chromaSize;
- }
- ps_decode_ip->s_out_buffer.u4_num_bufs = 3;
- ps_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
-
- return true;
-}
-
-
-bool C2SoftMpeg2Dec::getSeqInfo() {
- ivdext_ctl_get_seq_info_ip_t s_ctl_get_seq_info_ip;
- ivdext_ctl_get_seq_info_op_t s_ctl_get_seq_info_op;
-
- s_ctl_get_seq_info_ip.u4_size = sizeof(ivdext_ctl_get_seq_info_ip_t);
- s_ctl_get_seq_info_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_ctl_get_seq_info_ip.e_sub_cmd =
- (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_GET_SEQ_INFO;
- s_ctl_get_seq_info_op.u4_size = sizeof(ivdext_ctl_get_seq_info_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_ctl_get_seq_info_ip,
- &s_ctl_get_seq_info_op);
- if (status != IV_SUCCESS) {
- ALOGW("Error in getting Sequence info: 0x%x", s_ctl_get_seq_info_op.u4_error_code);
- return false;
- }
-
- VuiColorAspects vuiColorAspects;
- vuiColorAspects.primaries = s_ctl_get_seq_info_op.u1_colour_primaries;
- vuiColorAspects.transfer = s_ctl_get_seq_info_op.u1_transfer_characteristics;
- vuiColorAspects.coeffs = s_ctl_get_seq_info_op.u1_matrix_coefficients;
- vuiColorAspects.fullRange = false; // mpeg2 video has limited range.
-
- // convert vui aspects to C2 values if changed
- if (!(vuiColorAspects == mBitstreamColorAspects)) {
- mBitstreamColorAspects = vuiColorAspects;
- ColorAspects sfAspects;
- C2StreamColorAspectsInfo::input codedAspects = { 0u };
- ColorUtils::convertIsoColorAspectsToCodecAspects(
- vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs,
- vuiColorAspects.fullRange, sfAspects);
- if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) {
- codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) {
- codedAspects.range = C2Color::RANGE_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) {
- codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED;
- }
- if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) {
- codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED;
- }
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- (void)mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures);
- }
- return true;
-}
-
-status_t C2SoftMpeg2Dec::setFlushMode() {
- ivd_ctl_flush_ip_t s_set_flush_ip;
- ivd_ctl_flush_op_t s_set_flush_op;
-
- s_set_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
- s_set_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_set_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
- s_set_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_set_flush_ip,
- &s_set_flush_op);
- if (status != IV_SUCCESS) {
- ALOGE("error in %s: 0x%x", __func__, s_set_flush_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::resetDecoder() {
- ivd_ctl_reset_ip_t s_reset_ip;
- ivd_ctl_reset_op_t s_reset_op;
-
- s_reset_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
- s_reset_ip.e_cmd = IVD_CMD_VIDEO_CTL;
- s_reset_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
- s_reset_op.u4_size = sizeof(ivd_ctl_reset_op_t);
- IV_API_CALL_STATUS_T status = ivdec_api_function(mDecHandle,
- &s_reset_ip,
- &s_reset_op);
- if (IV_SUCCESS != status) {
- ALOGE("error in %s: 0x%x", __func__, s_reset_op.u4_error_code);
- return UNKNOWN_ERROR;
- }
- (void) setNumCores();
- mStride = 0;
- mSignalledError = false;
-
- return OK;
-}
-
-void C2SoftMpeg2Dec::resetPlugin() {
- mSignalledOutputEos = false;
- gettimeofday(&mTimeStart, nullptr);
- gettimeofday(&mTimeEnd, nullptr);
-}
-
-status_t C2SoftMpeg2Dec::deleteDecoder() {
- if (mMemRecords) {
- iv_mem_rec_t *ps_mem_rec = mMemRecords;
-
- for (size_t i = 0; i < mNumMemRecords; i++, ps_mem_rec++) {
- if (ps_mem_rec->pv_base) {
- ivd_aligned_free(ps_mem_rec->pv_base);
- }
- }
- ivd_aligned_free(mMemRecords);
- mMemRecords = nullptr;
- }
- mDecHandle = nullptr;
-
- return OK;
-}
-
-status_t C2SoftMpeg2Dec::reInitDecoder() {
- deleteDecoder();
-
- status_t ret = initDecoder();
- if (OK != ret) {
- ALOGE("Failed to initialize decoder");
- deleteDecoder();
- return ret;
- }
- return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftMpeg2Dec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
- std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
- C2Rect(mWidth, mHeight));
- mOutBlock = nullptr;
- {
- IntfImpl::Lock lock = mIntf->lock();
- buffer->setInfo(mIntf->getColorAspects_l());
- }
-
- auto fillWork = [buffer](const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = (C2FrameData::flags_t)0;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
- fillWork(work);
- } else {
- finish(index, fillWork);
- }
-}
-
-c2_status_t C2SoftMpeg2Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
- if (!mDecHandle) {
- ALOGE("not supposed to be here, invalid decoder context");
- return C2_CORRUPTED;
- }
- if (mStride != ALIGN64(mWidth)) {
- mStride = ALIGN64(mWidth);
- if (OK != setParams(mStride)) return C2_CORRUPTED;
- }
- if (mOutBlock &&
- (mOutBlock->width() != mStride || mOutBlock->height() != mHeight)) {
- mOutBlock.reset();
- }
- if (!mOutBlock) {
- uint32_t format = HAL_PIXEL_FORMAT_YV12;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(mStride, mHeight, format, usage, &mOutBlock);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return err;
- }
- ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mStride, mHeight);
- }
-
- return C2_OK;
-}
-
-// TODO: can overall error checking be improved?
-// TODO: allow configuration of color format and usage for graphic buffers instead
-// of hard coding them to HAL_PIXEL_FORMAT_YV12
-// TODO: pass coloraspects information to surface
-// TODO: test support for dynamic change in resolution
-// TODO: verify if the decoder sent back all frames
-void C2SoftMpeg2Dec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 0u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- size_t inOffset = 0u;
- size_t inSize = 0u;
- uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- bool hasPicture = false;
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
- size_t inPos = 0;
- while (inPos < inSize) {
- if (C2_OK != ensureDecoderState(pool)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
-
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
- if (!setDecodeArgs(&s_decode_ip, &s_decode_op, &rView, &wView,
- inOffset + inPos, inSize - inPos, workIndex)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- // If input dump is enabled, then write to file
- DUMP_TO_FILE(mInFile, s_decode_ip.pv_stream_buffer, s_decode_ip.u4_num_Bytes);
- WORD32 delay;
- GETTIME(&mTimeStart, nullptr);
- TIME_DIFF(mTimeEnd, mTimeStart, delay);
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- WORD32 decodeTime;
- GETTIME(&mTimeEnd, nullptr);
- TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
- ALOGV("decodeTime=%6d delay=%6d numBytes=%6d ", decodeTime, delay,
- s_decode_op.u4_num_bytes_consumed);
- if (IMPEG2D_UNSUPPORTED_DIMENSIONS == s_decode_op.u4_error_code) {
- ALOGV("unsupported resolution : %dx%d", s_decode_op.u4_pic_wd, s_decode_op.u4_pic_ht);
- drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
- resetPlugin();
- work->workletsProcessed = 0u;
- mWidth = s_decode_op.u4_pic_wd;
- mHeight = s_decode_op.u4_pic_ht;
-
- ALOGI("Configuring decoder: mWidth %d , mHeight %d ",
- mWidth, mHeight);
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err =
- mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- } else {
- ALOGE("Cannot set width and height");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
-
- if (OK != reInitDecoder()) {
- ALOGE("Failed to reinitialize decoder");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- continue;
- } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
- ALOGV("resolution changed");
- drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
- resetDecoder();
- resetPlugin();
- work->workletsProcessed = 0u;
- continue;
- }
- if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
- if (s_decode_op.u4_pic_wd != mWidth || s_decode_op.u4_pic_ht != mHeight) {
- mWidth = s_decode_op.u4_pic_wd;
- mHeight = s_decode_op.u4_pic_ht;
- CHECK_EQ(0u, s_decode_op.u4_output_present);
-
- ALOGI("Configuring decoder out: mWidth %d , mHeight %d ",
- mWidth, mHeight);
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err =
- mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- } else {
- ALOGE("Cannot set width and height");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- }
-
- (void) getSeqInfo();
- hasPicture |= (1 == s_decode_op.u4_frame_decoded_flag);
- if (s_decode_op.u4_output_present) {
- finishWork(s_decode_op.u4_ts, work);
- }
-
- inPos += s_decode_op.u4_num_bytes_consumed;
- if (hasPicture && (inSize - inPos) != 0) {
- ALOGD("decoded frame in current access nal, ignoring further trailing bytes %d",
- (int)inSize - (int)inPos);
- break;
- }
- }
-
- if (eos) {
- drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
- mSignalledOutputEos = true;
- } else if (!hasPicture) {
- fillEmptyWork(work);
- }
-}
-
-c2_status_t C2SoftMpeg2Dec::drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work) {
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- if (OK != setFlushMode()) return C2_CORRUPTED;
- while (true) {
- if (C2_OK != ensureDecoderState(pool)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return C2_CORRUPTED;
- }
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- return C2_CORRUPTED;
- }
- ivd_video_decode_ip_t s_decode_ip;
- ivd_video_decode_op_t s_decode_op;
- if (!setDecodeArgs(&s_decode_ip, &s_decode_op, nullptr, &wView, 0, 0, 0)) {
- mSignalledError = true;
- work->workletsProcessed = 1u;
- return C2_CORRUPTED;
- }
- (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
- if (s_decode_op.u4_output_present) {
- finishWork(s_decode_op.u4_ts, work);
- } else {
- fillEmptyWork(work);
- break;
- }
- }
-
- return C2_OK;
-}
-
-c2_status_t C2SoftMpeg2Dec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftMpeg2DecFactory : public C2ComponentFactory {
-public:
- C2SoftMpeg2DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftMpeg2Dec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftMpeg2Dec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftMpeg2Dec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftMpeg2Dec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftMpeg2DecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftMpeg2DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/mpeg2/C2SoftMpeg2Dec.h b/media/codecs/mpeg2/C2SoftMpeg2Dec.h
deleted file mode 100644
index 9999872..0000000
--- a/media/codecs/mpeg2/C2SoftMpeg2Dec.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_MPEG2_DEC_H_
-#define ANDROID_C2_SOFT_MPEG2_DEC_H_
-
-#include <SimpleC2Component.h>
-
-#include <media/stagefright/foundation/ColorUtils.h>
-
-#include "iv_datatypedef.h"
-#include "iv.h"
-#include "ivd.h"
-
-namespace android {
-
-#define ivdec_api_function impeg2d_api_function
-#define ivdext_init_ip_t impeg2d_init_ip_t
-#define ivdext_init_op_t impeg2d_init_op_t
-#define ivdext_fill_mem_rec_ip_t impeg2d_fill_mem_rec_ip_t
-#define ivdext_fill_mem_rec_op_t impeg2d_fill_mem_rec_op_t
-#define ivdext_ctl_set_num_cores_ip_t impeg2d_ctl_set_num_cores_ip_t
-#define ivdext_ctl_set_num_cores_op_t impeg2d_ctl_set_num_cores_op_t
-#define ivdext_ctl_get_seq_info_ip_t impeg2d_ctl_get_seq_info_ip_t
-#define ivdext_ctl_get_seq_info_op_t impeg2d_ctl_get_seq_info_op_t
-#define ALIGN64(x) ((((x) + 63) >> 6) << 6)
-#define MAX_NUM_CORES 4
-#define IVDEXT_CMD_CTL_SET_NUM_CORES \
- (IVD_CONTROL_API_COMMAND_TYPE_T)IMPEG2D_CMD_CTL_SET_NUM_CORES
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define GETTIME(a, b) gettimeofday(a, b);
-#define TIME_DIFF(start, end, diff) \
- diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
- ((end).tv_usec - (start).tv_usec);
-
-#ifdef FILE_DUMP_ENABLE
- #define INPUT_DUMP_PATH "/sdcard/clips/mpeg2d_input"
- #define INPUT_DUMP_EXT "m2v"
- #define GENERATE_FILE_NAMES() { \
- GETTIME(&mTimeStart, NULL); \
- strcpy(mInFile, ""); \
- sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH, \
- mTimeStart.tv_sec, mTimeStart.tv_usec, \
- INPUT_DUMP_EXT); \
- }
- #define CREATE_DUMP_FILE(m_filename) { \
- FILE *fp = fopen(m_filename, "wb"); \
- if (fp != NULL) { \
- fclose(fp); \
- } else { \
- ALOGD("Could not open file %s", m_filename); \
- } \
- }
- #define DUMP_TO_FILE(m_filename, m_buf, m_size) \
- { \
- FILE *fp = fopen(m_filename, "ab"); \
- if (fp != NULL && m_buf != NULL) { \
- uint32_t i; \
- i = fwrite(m_buf, 1, m_size, fp); \
- ALOGD("fwrite ret %d to write %d", i, m_size); \
- if (i != (uint32_t)m_size) { \
- ALOGD("Error in fwrite, returned %d", i); \
- perror("Error in write to file"); \
- } \
- fclose(fp); \
- } else { \
- ALOGD("Could not write to file %s", m_filename);\
- } \
- }
-#else /* FILE_DUMP_ENABLE */
- #define INPUT_DUMP_PATH
- #define INPUT_DUMP_EXT
- #define OUTPUT_DUMP_PATH
- #define OUTPUT_DUMP_EXT
- #define GENERATE_FILE_NAMES()
- #define CREATE_DUMP_FILE(m_filename)
- #define DUMP_TO_FILE(m_filename, m_buf, m_size)
-#endif /* FILE_DUMP_ENABLE */
-
-struct C2SoftMpeg2Dec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftMpeg2Dec(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftMpeg2Dec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
- private:
- status_t getNumMemRecords();
- status_t fillMemRecords();
- status_t createDecoder();
- status_t setNumCores();
- status_t setParams(size_t stride);
- status_t getVersion();
- status_t initDecoder();
- bool setDecodeArgs(ivd_video_decode_ip_t *ps_decode_ip,
- ivd_video_decode_op_t *ps_decode_op,
- C2ReadView *inBuffer,
- C2GraphicView *outBuffer,
- size_t inOffset,
- size_t inSize,
- uint32_t tsMarker);
- bool getSeqInfo();
- c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
- void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
- status_t setFlushMode();
- c2_status_t drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work);
- status_t resetDecoder();
- void resetPlugin();
- status_t deleteDecoder();
- status_t reInitDecoder();
-
- // TODO:This is not the right place for this enum. These should
- // be part of c2-vndk so that they can be accessed by all video plugins
- // until then, make them feel at home
- enum {
- kNotSupported,
- kPreferBitstream,
- kPreferContainer,
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- iv_obj_t *mDecHandle;
- iv_mem_rec_t *mMemRecords;
- size_t mNumMemRecords;
- std::shared_ptr<C2GraphicBlock> mOutBlock;
- uint8_t *mOutBufferDrain;
-
- size_t mNumCores;
- IV_COLOR_FORMAT_T mIvColorformat;
-
- uint32_t mWidth;
- uint32_t mHeight;
- uint32_t mStride;
- bool mSignalledOutputEos;
- bool mSignalledError;
-
- // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid
- // converting them to C2 values for each frame
- struct VuiColorAspects {
- uint8_t primaries;
- uint8_t transfer;
- uint8_t coeffs;
- uint8_t fullRange;
-
- // default color aspects
- VuiColorAspects()
- : primaries(2), transfer(2), coeffs(2), fullRange(0) { }
-
- bool operator==(const VuiColorAspects &o) {
- return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs
- && fullRange == o.fullRange;
- }
- } mBitstreamColorAspects;
-
- // profile
- struct timeval mTimeStart;
- struct timeval mTimeEnd;
-#ifdef FILE_DUMP_ENABLE
- char mInFile[200];
-#endif /* FILE_DUMP_ENABLE */
-
- C2_DO_NOT_COPY(C2SoftMpeg2Dec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_MPEG2_DEC_H_
diff --git a/media/codecs/mpeg4_h263/Android.bp b/media/codecs/mpeg4_h263/Android.bp
deleted file mode 100644
index 3155bc2..0000000
--- a/media/codecs/mpeg4_h263/Android.bp
+++ /dev/null
@@ -1,66 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2mpeg4dec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- srcs: ["C2SoftMpeg4Dec.cpp"],
-
- static_libs: ["libstagefright_m4vh263dec"],
-
- cflags: [
- "-DOSCL_IMPORT_REF=",
- "-DMPEG4",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2h263dec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- srcs: ["C2SoftMpeg4Dec.cpp"],
-
- static_libs: ["libstagefright_m4vh263dec"],
-
- cflags: [
- "-DOSCL_IMPORT_REF=",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2mpeg4enc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
-
- srcs: ["C2SoftMpeg4Enc.cpp"],
-
- static_libs: ["libstagefright_m4vh263enc"],
-
- cflags: [
- "-DMPEG4",
- "-DOSCL_IMPORT_REF=",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2h263enc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_signed-defaults",
- ],
-
- srcs: ["C2SoftMpeg4Enc.cpp"],
-
- static_libs: [ "libstagefright_m4vh263enc" ],
-
- cflags: [
- "-DOSCL_IMPORT_REF=",
- ],
-}
diff --git a/media/codecs/mpeg4_h263/C2SoftMpeg4Dec.cpp b/media/codecs/mpeg4_h263/C2SoftMpeg4Dec.cpp
deleted file mode 100644
index 901f5ed..0000000
--- a/media/codecs/mpeg4_h263/C2SoftMpeg4Dec.cpp
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (C) 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
-#ifdef MPEG4
- #define LOG_TAG "C2SoftMpeg4Dec"
-#else
- #define LOG_TAG "C2SoftH263Dec"
-#endif
-#include <log/log.h>
-
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftMpeg4Dec.h"
-#include "mp4dec_api.h"
-
-namespace android {
-
-#ifdef MPEG4
-constexpr char COMPONENT_NAME[] = "c2.android.mpeg4.decoder";
-#else
-constexpr char COMPONENT_NAME[] = "c2.android.h263.decoder";
-#endif
-
-class C2SoftMpeg4Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : SimpleInterface<void>::BaseParams(
- helper,
- COMPONENT_NAME,
- C2Component::KIND_DECODER,
- C2Component::DOMAIN_VIDEO,
-#ifdef MPEG4
- MEDIA_MIMETYPE_VIDEO_MPEG4
-#else
- MEDIA_MIMETYPE_VIDEO_H263
-#endif
- ) {
- noPrivateBuffers(); // TODO: account for our buffers here
- noInputReferences();
- noOutputReferences();
- noInputLatency();
- noTimeStretch();
-
- // TODO: output latency and reordering
-
- addParameter(
- DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
- .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::output(0u, 176, 144))
- .withFields({
-#ifdef MPEG4
- C2F(mSize, width).inRange(2, 1920, 2),
- C2F(mSize, height).inRange(2, 1088, 2),
-#else
- C2F(mSize, width).inRange(2, 352, 2),
- C2F(mSize, height).inRange(2, 288, 2),
-#endif
- })
- .withSetter(SizeSetter)
- .build());
-
-#ifdef MPEG4
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_MP4V_SIMPLE, C2Config::LEVEL_MP4V_3))
- .withFields({
- C2F(mProfileLevel, profile).equalTo(
- C2Config::PROFILE_MP4V_SIMPLE),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_MP4V_0,
- C2Config::LEVEL_MP4V_0B,
- C2Config::LEVEL_MP4V_1,
- C2Config::LEVEL_MP4V_2,
- C2Config::LEVEL_MP4V_3,
- C2Config::LEVEL_MP4V_3B,
- C2Config::LEVEL_MP4V_4,
- C2Config::LEVEL_MP4V_4A,
- C2Config::LEVEL_MP4V_5,
- C2Config::LEVEL_MP4V_6})
- })
- .withSetter(ProfileLevelSetter, mSize)
- .build());
-#else
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_H263_BASELINE, C2Config::LEVEL_H263_30))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_H263_BASELINE,
- C2Config::PROFILE_H263_ISWV2}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_H263_10,
- C2Config::LEVEL_H263_20,
- C2Config::LEVEL_H263_30,
- C2Config::LEVEL_H263_40,
- C2Config::LEVEL_H263_45})
- })
- .withSetter(ProfileLevelSetter, mSize)
- .build());
-#endif
-
- addParameter(
- DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
-#ifdef MPEG4
- .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 1920, 1088))
-#else
- .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 352, 288))
-#endif
- .withFields({
-#ifdef MPEG4
- C2F(mSize, width).inRange(2, 1920, 2),
- C2F(mSize, height).inRange(2, 1088, 2),
-#else
- C2F(mSize, width).inRange(2, 352, 2),
- C2F(mSize, height).inRange(2, 288, 2),
-#endif
- })
- .withSetter(MaxPictureSizeSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
-#ifdef MPEG4
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 1920 * 1088 * 3 / 2))
-#else
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 352 * 288 * 3 / 2))
-#endif
- .withFields({
- C2F(mMaxInputSize, value).any(),
- })
- .calculatedAs(MaxInputSizeSetter, mMaxSize)
- .build());
-
- C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
- std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- 1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
- memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
-
- defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- { C2ChromaOffsetStruct::ITU_YUV_420_0() },
- 0u, 8u /* bitDepth */, C2Color::YUV_420);
- helper->addStructDescriptors<C2ChromaOffsetStruct>();
-
- addParameter(
- DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
- .withConstValue(defaultColorInfo)
- .build());
-
- // TODO: support more formats?
- addParameter(
- DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
- .build());
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
- C2P<C2VideoSizeStreamInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- // TODO: get max width/height from the size's field helpers vs. hardcoding
-#ifdef MPEG4
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 1920u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 1088u);
-#else
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 352u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 288u);
-#endif
- return C2R::Ok();
- }
-
- static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
- const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
- (void)mayBlock;
- // assume compression ratio of 1
- me.set().value = (((maxSize.v.width + 15) / 16) * ((maxSize.v.height + 15) / 16) * 384);
- return C2R::Ok();
- }
-
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- (void)size;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- uint32_t getMaxWidth() const { return mMaxSize->width; }
- uint32_t getMaxHeight() const { return mMaxSize->height; }
-
-private:
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
- std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
- std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
- std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
-};
-
-C2SoftMpeg4Dec::C2SoftMpeg4Dec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mDecHandle(nullptr),
- mOutputBuffer{},
- mInitialized(false) {
-}
-
-C2SoftMpeg4Dec::~C2SoftMpeg4Dec() {
- onRelease();
-}
-
-c2_status_t C2SoftMpeg4Dec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftMpeg4Dec::onStop() {
- if (mInitialized) {
- if (mDecHandle) {
- PVCleanUpVideoDecoder(mDecHandle);
- }
- mInitialized = false;
- }
- for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
- if (mOutputBuffer[i]) {
- free(mOutputBuffer[i]);
- mOutputBuffer[i] = nullptr;
- }
- }
- mNumSamplesOutput = 0;
- mFramesConfigured = false;
- mSignalledOutputEos = false;
- mSignalledError = false;
-
- return C2_OK;
-}
-
-void C2SoftMpeg4Dec::onReset() {
- (void)onStop();
- (void)onInit();
-}
-
-void C2SoftMpeg4Dec::onRelease() {
- if (mInitialized) {
- if (mDecHandle) {
- PVCleanUpVideoDecoder(mDecHandle);
- delete mDecHandle;
- mDecHandle = nullptr;
- }
- mInitialized = false;
- }
- if (mOutBlock) {
- mOutBlock.reset();
- }
- for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
- if (mOutputBuffer[i]) {
- free(mOutputBuffer[i]);
- mOutputBuffer[i] = nullptr;
- }
- }
-}
-
-c2_status_t C2SoftMpeg4Dec::onFlush_sm() {
- if (mInitialized) {
- if (PV_TRUE != PVResetVideoDecoder(mDecHandle)) {
- return C2_CORRUPTED;
- }
- }
- mSignalledOutputEos = false;
- mSignalledError = false;
- return C2_OK;
-}
-
-status_t C2SoftMpeg4Dec::initDecoder() {
-#ifdef MPEG4
- mIsMpeg4 = true;
-#else
- mIsMpeg4 = false;
-#endif
- if (!mDecHandle) {
- mDecHandle = new tagvideoDecControls;
- }
- if (!mDecHandle) {
- ALOGE("mDecHandle is null");
- return NO_MEMORY;
- }
- memset(mDecHandle, 0, sizeof(tagvideoDecControls));
-
- /* TODO: bring these values to 352 and 288. It cannot be done as of now
- * because, h263 doesn't seem to allow port reconfiguration. In OMX, the
- * problem of larger width and height than default width and height is
- * overcome by adaptivePlayBack() api call. This call gets width and height
- * information from extractor. Such a thing is not possible here.
- * So we are configuring to larger values.*/
- mWidth = 1408;
- mHeight = 1152;
- mNumSamplesOutput = 0;
- mInitialized = false;
- mFramesConfigured = false;
- mSignalledOutputEos = false;
- mSignalledError = false;
-
- return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftMpeg4Dec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work) {
- std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(std::move(mOutBlock),
- C2Rect(mWidth, mHeight));
- mOutBlock = nullptr;
- auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
- (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
- fillWork(work);
- } else {
- finish(index, fillWork);
- }
-}
-
-c2_status_t C2SoftMpeg4Dec::ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool) {
- if (!mDecHandle) {
- ALOGE("not supposed to be here, invalid decoder context");
- return C2_CORRUPTED;
- }
-
- mOutputBufferSize = align(mIntf->getMaxWidth(), 16) * align(mIntf->getMaxHeight(), 16) * 3 / 2;
- for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
- if (!mOutputBuffer[i]) {
- mOutputBuffer[i] = (uint8_t *)malloc(mOutputBufferSize);
- if (!mOutputBuffer[i]) {
- return C2_NO_MEMORY;
- }
- }
- }
- if (mOutBlock &&
- (mOutBlock->width() != align(mWidth, 16) || mOutBlock->height() != mHeight)) {
- mOutBlock.reset();
- }
- if (!mOutBlock) {
- uint32_t format = HAL_PIXEL_FORMAT_YV12;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &mOutBlock);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- return err;
- }
- ALOGV("provided (%dx%d) required (%dx%d)",
- mOutBlock->width(), mOutBlock->height(), mWidth, mHeight);
- }
- return C2_OK;
-}
-
-bool C2SoftMpeg4Dec::handleResChange(const std::unique_ptr<C2Work> &work) {
- uint32_t disp_width, disp_height;
- PVGetVideoDimensions(mDecHandle, (int32 *)&disp_width, (int32 *)&disp_height);
-
- uint32_t buf_width, buf_height;
- PVGetBufferDimensions(mDecHandle, (int32 *)&buf_width, (int32 *)&buf_height);
-
- CHECK_LE(disp_width, buf_width);
- CHECK_LE(disp_height, buf_height);
-
- ALOGV("display size (%dx%d), buffer size (%dx%d)",
- disp_width, disp_height, buf_width, buf_height);
-
- bool resChanged = false;
- if (disp_width != mWidth || disp_height != mHeight) {
- mWidth = disp_width;
- mHeight = disp_height;
- resChanged = true;
- for (int32_t i = 0; i < kNumOutputBuffers; ++i) {
- if (mOutputBuffer[i]) {
- free(mOutputBuffer[i]);
- mOutputBuffer[i] = nullptr;
- }
- }
-
- if (!mIsMpeg4) {
- PVCleanUpVideoDecoder(mDecHandle);
-
- uint8_t *vol_data[1]{};
- int32_t vol_size = 0;
-
- if (!PVInitVideoDecoder(
- mDecHandle, vol_data, &vol_size, 1, mIntf->getMaxWidth(), mIntf->getMaxHeight(), H263_MODE)) {
- ALOGE("Error in PVInitVideoDecoder H263_MODE while resChanged was set to true");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return true;
- }
- }
- mFramesConfigured = false;
- }
- return resChanged;
-}
-
-/* TODO: can remove temporary copy after library supports writing to display
- * buffer Y, U and V plane pointers using stride info. */
-static void copyOutputBufferToYV12Frame(uint8_t *dst, uint8_t *src, size_t dstYStride,
- size_t srcYStride, uint32_t width, uint32_t height) {
- size_t dstUVStride = align(dstYStride / 2, 16);
- size_t srcUVStride = srcYStride / 2;
- uint8_t *srcStart = src;
- uint8_t *dstStart = dst;
- size_t vStride = align(height, 16);
- for (size_t i = 0; i < height; ++i) {
- memcpy(dst, src, width);
- src += srcYStride;
- dst += dstYStride;
- }
- /* U buffer */
- src = srcStart + vStride * srcYStride;
- dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
- for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, src, width / 2);
- src += srcUVStride;
- dst += dstUVStride;
- }
- /* V buffer */
- src = srcStart + vStride * srcYStride * 5 / 4;
- dst = dstStart + (dstYStride * height);
- for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, src, width / 2);
- src += srcUVStride;
- dst += dstUVStride;
- }
-}
-
-void C2SoftMpeg4Dec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- size_t inOffset = 0u;
- size_t inSize = 0u;
- uint32_t workIndex = work->input.ordinal.frameIndex.peeku() & 0xFFFFFFFF;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- if (inSize == 0) {
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- }
- return;
- }
-
- uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
- uint32_t *start_code = (uint32_t *)bitstream;
- bool volHeader = *start_code == 0xB0010000;
- if (volHeader) {
- PVCleanUpVideoDecoder(mDecHandle);
- mInitialized = false;
- }
-
- if (!mInitialized) {
- uint8_t *vol_data[1]{};
- int32_t vol_size = 0;
-
- bool codecConfig = (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
- if (codecConfig || volHeader) {
- vol_data[0] = bitstream;
- vol_size = inSize;
- }
- MP4DecodingMode mode = (mIsMpeg4) ? MPEG4_MODE : H263_MODE;
- if (!PVInitVideoDecoder(
- mDecHandle, vol_data, &vol_size, 1,
- mIntf->getMaxWidth(), mIntf->getMaxHeight(), mode)) {
- ALOGE("PVInitVideoDecoder failed. Unsupported content?");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- mInitialized = true;
- MP4DecodingMode actualMode = PVGetDecBitstreamMode(mDecHandle);
- if (mode != actualMode) {
- ALOGE("Decoded mode not same as actual mode of the decoder");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- PVSetPostProcType(mDecHandle, 0);
- if (handleResChange(work)) {
- ALOGI("Setting width and height");
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- } else {
- ALOGE("Config update size failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- if (codecConfig) {
- fillEmptyWork(work);
- return;
- }
- }
-
- size_t inPos = 0;
- while (inPos < inSize) {
- c2_status_t err = ensureDecoderState(pool);
- if (C2_OK != err) {
- mSignalledError = true;
- work->result = err;
- return;
- }
- C2GraphicView wView = mOutBlock->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
-
- uint32_t yFrameSize = sizeof(uint8) * mDecHandle->size;
- if (mOutputBufferSize < yFrameSize * 3 / 2){
- ALOGE("Too small output buffer: %zu bytes", mOutputBufferSize);
- mSignalledError = true;
- work->result = C2_NO_MEMORY;
- return;
- }
-
- if (!mFramesConfigured) {
- PVSetReferenceYUV(mDecHandle,mOutputBuffer[1]);
- mFramesConfigured = true;
- }
-
- // Need to check if header contains new info, e.g., width/height, etc.
- VopHeaderInfo header_info;
- uint32_t useExtTimestamp = (inPos == 0);
- int32_t tmpInSize = (int32_t)inSize;
- uint8_t *bitstreamTmp = bitstream;
- uint32_t timestamp = workIndex;
- if (PVDecodeVopHeader(
- mDecHandle, &bitstreamTmp, &timestamp, &tmpInSize,
- &header_info, &useExtTimestamp,
- mOutputBuffer[mNumSamplesOutput & 1]) != PV_TRUE) {
- ALOGE("failed to decode vop header.");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- // H263 doesn't have VOL header, the frame size information is in short header, i.e. the
- // decoder may detect size change after PVDecodeVopHeader.
- bool resChange = handleResChange(work);
- if (mIsMpeg4 && resChange) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- } else if (resChange) {
- ALOGI("Setting width and height");
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(size));
- } else {
- ALOGE("Config update size failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- continue;
- }
-
- if (PVDecodeVopBody(mDecHandle, &tmpInSize) != PV_TRUE) {
- ALOGE("failed to decode video frame.");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- if (handleResChange(work)) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- uint8_t *outputBufferY = wView.data()[C2PlanarLayout::PLANE_Y];
- (void)copyOutputBufferToYV12Frame(outputBufferY, mOutputBuffer[mNumSamplesOutput & 1],
- wView.width(), align(mWidth, 16), mWidth, mHeight);
-
- inPos += inSize - (size_t)tmpInSize;
- finishWork(workIndex, work);
- ++mNumSamplesOutput;
- if (inSize - inPos != 0) {
- ALOGD("decoded frame, ignoring further trailing bytes %d",
- (int)inSize - (int)inPos);
- break;
- }
- }
-}
-
-c2_status_t C2SoftMpeg4Dec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void)pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
- return C2_OK;
-}
-
-class C2SoftMpeg4DecFactory : public C2ComponentFactory {
-public:
- C2SoftMpeg4DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftMpeg4Dec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftMpeg4Dec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftMpeg4Dec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftMpeg4Dec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftMpeg4DecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftMpeg4DecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/mpeg4_h263/C2SoftMpeg4Dec.h b/media/codecs/mpeg4_h263/C2SoftMpeg4Dec.h
deleted file mode 100644
index 716a095..0000000
--- a/media/codecs/mpeg4_h263/C2SoftMpeg4Dec.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef C2_SOFT_MPEG4_DEC_H_
-#define C2_SOFT_MPEG4_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-struct tagvideoDecControls;
-
-namespace android {
-
-struct C2SoftMpeg4Dec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftMpeg4Dec(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftMpeg4Dec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
- private:
- enum {
- kNumOutputBuffers = 2,
- };
-
- status_t initDecoder();
- c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool);
- void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work);
- bool handleResChange(const std::unique_ptr<C2Work> &work);
-
- std::shared_ptr<IntfImpl> mIntf;
- tagvideoDecControls *mDecHandle;
- std::shared_ptr<C2GraphicBlock> mOutBlock;
- uint8_t *mOutputBuffer[kNumOutputBuffers];
- size_t mOutputBufferSize;
-
- uint32_t mWidth;
- uint32_t mHeight;
- uint32_t mNumSamplesOutput;
-
- bool mIsMpeg4;
- bool mInitialized;
- bool mFramesConfigured;
- bool mSignalledOutputEos;
- bool mSignalledError;
-
- C2_DO_NOT_COPY(C2SoftMpeg4Dec);
-};
-
-} // namespace android
-
-#endif // C2_SOFT_MPEG4_DEC_H_
diff --git a/media/codecs/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codecs/mpeg4_h263/C2SoftMpeg4Enc.cpp
deleted file mode 100644
index c8796f3..0000000
--- a/media/codecs/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * 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
-#ifdef MPEG4
- #define LOG_TAG "C2SoftMpeg4Enc"
-#else
- #define LOG_TAG "C2SoftH263Enc"
-#endif
-#include <log/log.h>
-
-#include <inttypes.h>
-
-#include <media/hardware/VideoAPI.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaDefs.h>
-#include <utils/misc.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-#include <util/C2InterfaceHelper.h>
-
-#include "C2SoftMpeg4Enc.h"
-#include "mp4enc_api.h"
-
-namespace android {
-
-#ifdef MPEG4
-constexpr char COMPONENT_NAME[] = "c2.android.mpeg4.encoder";
-#else
-constexpr char COMPONENT_NAME[] = "c2.android.h263.encoder";
-#endif
-
-class C2SoftMpeg4Enc::IntfImpl : public C2InterfaceHelper {
- public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::input(0u, C2FormatVideo))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_VIDEO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
-#ifdef MPEG4
- MEDIA_MIMETYPE_VIDEO_MPEG4
-#else
- MEDIA_MIMETYPE_VIDEO_H263
-#endif
- ))
- .build());
-
- addParameter(DefineParam(mUsage, C2_NAME_INPUT_STREAM_USAGE_SETTING)
- .withConstValue(new C2StreamUsageTuning::input(
- 0u, (uint64_t)C2MemoryUsage::CPU_READ))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_NAME_STREAM_VIDEO_SIZE_SETTING)
- .withDefault(new C2VideoSizeStreamTuning::input(0u, 176, 144))
- .withFields({
-#ifdef MPEG4
- C2F(mSize, width).inRange(16, 176, 16),
- C2F(mSize, height).inRange(16, 144, 16),
-#else
- C2F(mSize, width).oneOf({176, 352}),
- C2F(mSize, height).oneOf({144, 288}),
-#endif
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mFrameRate, C2_NAME_STREAM_FRAME_RATE_SETTING)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 17.))
- // TODO: More restriction?
- .withFields({C2F(mFrameRate, value).greaterThan(0.)})
- .withSetter(
- Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
- .withSetter(BitrateSetter)
- .build());
-
- addParameter(
- DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
- .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
- .withFields({C2F(mSyncFramePeriod, value).any()})
- .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
- .build());
-
-#ifdef MPEG4
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::output(
- 0u, PROFILE_MP4V_SIMPLE, LEVEL_MP4V_2))
- .withFields({
- C2F(mProfileLevel, profile).equalTo(
- PROFILE_MP4V_SIMPLE),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_MP4V_0,
- C2Config::LEVEL_MP4V_0B,
- C2Config::LEVEL_MP4V_1,
- C2Config::LEVEL_MP4V_2})
- })
- .withSetter(ProfileLevelSetter)
- .build());
-#else
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::output(
- 0u, PROFILE_H263_BASELINE, LEVEL_H263_45))
- .withFields({
- C2F(mProfileLevel, profile).equalTo(
- PROFILE_H263_BASELINE),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_H263_10,
- C2Config::LEVEL_H263_20,
- C2Config::LEVEL_H263_30,
- C2Config::LEVEL_H263_40,
- C2Config::LEVEL_H263_45})
- })
- .withSetter(ProfileLevelSetter)
- .build());
-#endif
- }
-
- static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.value <= 4096) {
- me.set().value = 4096;
- }
- return res;
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
- C2P<C2StreamPictureSizeInfo::input> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R ProfileLevelSetter(
- bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output> &me) {
- (void)mayBlock;
- if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
-#ifdef MPEG4
- me.set().profile = PROFILE_MP4V_SIMPLE;
-#else
- me.set().profile = PROFILE_H263_BASELINE;
-#endif
- }
- if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
-#ifdef MPEG4
- me.set().level = LEVEL_MP4V_2;
-#else
- me.set().level = LEVEL_H263_45;
-#endif
- }
- return C2R::Ok();
- }
-
- // unsafe getters
- std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
- std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
- std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
- uint32_t getSyncFramePeriod() const {
- if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
- return 0;
- }
- double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
- return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
- }
-
- private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamUsageTuning::input> mUsage;
- std::shared_ptr<C2VideoSizeStreamTuning::input> mSize;
- std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
- std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
-};
-
-C2SoftMpeg4Enc::C2SoftMpeg4Enc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : SimpleC2Component(
- std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mHandle(nullptr),
- mEncParams(nullptr),
- mStarted(false),
- mOutBufferSize(524288) {
-}
-
-C2SoftMpeg4Enc::~C2SoftMpeg4Enc() {
- onRelease();
-}
-
-c2_status_t C2SoftMpeg4Enc::onInit() {
-#ifdef MPEG4
- mEncodeMode = COMBINE_MODE_WITH_ERR_RES;
-#else
- mEncodeMode = H263_MODE;
-#endif
- if (!mHandle) {
- mHandle = new tagvideoEncControls;
- }
-
- if (!mEncParams) {
- mEncParams = new tagvideoEncOptions;
- }
-
- if (!(mEncParams && mHandle)) return C2_NO_MEMORY;
-
- mSignalledOutputEos = false;
- mSignalledError = false;
-
- return initEncoder();
-}
-
-c2_status_t C2SoftMpeg4Enc::onStop() {
- if (!mStarted) {
- return C2_OK;
- }
- if (mHandle) {
- (void)PVCleanUpVideoEncoder(mHandle);
- }
- mStarted = false;
- mSignalledOutputEos = false;
- mSignalledError = false;
- return C2_OK;
-}
-
-void C2SoftMpeg4Enc::onReset() {
- onStop();
- initEncoder();
-}
-
-void C2SoftMpeg4Enc::onRelease() {
- onStop();
- if (mEncParams) {
- delete mEncParams;
- mEncParams = nullptr;
- }
- if (mHandle) {
- delete mHandle;
- mHandle = nullptr;
- }
-}
-
-c2_status_t C2SoftMpeg4Enc::onFlush_sm() {
- return C2_OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-c2_status_t C2SoftMpeg4Enc::initEncParams() {
- if (mHandle) {
- memset(mHandle, 0, sizeof(tagvideoEncControls));
- } else return C2_CORRUPTED;
- if (mEncParams) {
- memset(mEncParams, 0, sizeof(tagvideoEncOptions));
- } else return C2_CORRUPTED;
-
- if (!PVGetDefaultEncOption(mEncParams, 0)) {
- ALOGE("Failed to get default encoding parameters");
- return C2_CORRUPTED;
- }
-
- if (mFrameRate->value == 0) {
- ALOGE("Framerate should not be 0");
- return C2_BAD_VALUE;
- }
-
- mEncParams->encMode = mEncodeMode;
- mEncParams->encWidth[0] = mSize->width;
- mEncParams->encHeight[0] = mSize->height;
- mEncParams->encFrameRate[0] = mFrameRate->value + 0.5;
- mEncParams->rcType = VBR_1;
- mEncParams->vbvDelay = 5.0f;
- mEncParams->profile_level = CORE_PROFILE_LEVEL2;
- mEncParams->packetSize = 32;
- mEncParams->rvlcEnable = PV_OFF;
- mEncParams->numLayers = 1;
- mEncParams->timeIncRes = 1000;
- mEncParams->tickPerSrc = mEncParams->timeIncRes / (mFrameRate->value + 0.5);
- mEncParams->bitRate[0] = mBitrate->value;
- mEncParams->iQuant[0] = 15;
- mEncParams->pQuant[0] = 12;
- mEncParams->quantType[0] = 0;
- mEncParams->noFrameSkipped = PV_OFF;
-
- // PV's MPEG4 encoder requires the video dimension of multiple
- if (mSize->width % 16 != 0 || mSize->height % 16 != 0) {
- ALOGE("Video frame size %dx%d must be a multiple of 16",
- mSize->width, mSize->height);
- return C2_BAD_VALUE;
- }
-
- // Set IDR frame refresh interval
- mEncParams->intraPeriod = mIntf->getSyncFramePeriod();
- mEncParams->numIntraMB = 0;
- mEncParams->sceneDetect = PV_ON;
- mEncParams->searchRange = 16;
- mEncParams->mv8x8Enable = PV_OFF;
- mEncParams->gobHeaderInterval = 0;
- mEncParams->useACPred = PV_ON;
- mEncParams->intraDCVlcTh = 0;
-
- return C2_OK;
-}
-
-c2_status_t C2SoftMpeg4Enc::initEncoder() {
- if (mStarted) {
- return C2_OK;
- }
- {
- IntfImpl::Lock lock = mIntf->lock();
- mSize = mIntf->getSize_l();
- mBitrate = mIntf->getBitrate_l();
- mFrameRate = mIntf->getFrameRate_l();
- }
- c2_status_t err = initEncParams();
- if (C2_OK != err) {
- ALOGE("Failed to initialized encoder params");
- mSignalledError = true;
- return err;
- }
- if (!PVInitVideoEncoder(mHandle, mEncParams)) {
- ALOGE("Failed to initialize the encoder");
- mSignalledError = true;
- return C2_CORRUPTED;
- }
-
- // 1st buffer for codec specific data
- mNumInputFrames = -1;
- mStarted = true;
- return C2_OK;
-}
-
-void C2SoftMpeg4Enc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- // Initialize encoder if not already initialized
- if (!mStarted && C2_OK != initEncoder()) {
- ALOGE("Failed to initialize encoder");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(mOutBufferSize, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
-
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
-
- uint8_t *outPtr = (uint8_t *)wView.data();
- if (mNumInputFrames < 0) {
- // The very first thing we want to output is the codec specific data.
- int32_t outputSize = mOutBufferSize;
- if (!PVGetVolHeader(mHandle, outPtr, &outputSize, 0)) {
- ALOGE("Failed to get VOL header");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- } else {
- ALOGV("Bytes Generated in header %d\n", outputSize);
- }
-
- ++mNumInputFrames;
- std::unique_ptr<C2StreamCsdInfo::output> csd =
- C2StreamCsdInfo::output::AllocUnique(outputSize, 0u);
- if (!csd) {
- ALOGE("CSD allocation failed");
- mSignalledError = true;
- work->result = C2_NO_MEMORY;
- return;
- }
- memcpy(csd->m.value, outPtr, outputSize);
- work->worklets.front()->output.configUpdate.push_back(std::move(csd));
- }
-
- std::shared_ptr<const C2GraphicView> rView;
- std::shared_ptr<C2Buffer> inputBuffer;
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- if (!work->input.buffers.empty()) {
- inputBuffer = work->input.buffers[0];
- rView = std::make_shared<const C2GraphicView>(
- inputBuffer->data().graphicBlocks().front().map().get());
- if (rView->error() != C2_OK) {
- ALOGE("graphic view map err = %d", rView->error());
- work->result = rView->error();
- return;
- }
- } else {
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- uint64_t inputTimeStamp = work->input.ordinal.timestamp.peekull();
- const C2ConstGraphicBlock inBuffer = inputBuffer->data().graphicBlocks().front();
- if (inBuffer.width() < mSize->width ||
- inBuffer.height() < mSize->height) {
- /* Expect width height to be configured */
- ALOGW("unexpected Capacity Aspect %d(%d) x %d(%d)", inBuffer.width(),
- mSize->width, inBuffer.height(), mSize->height);
- work->result = C2_BAD_VALUE;
- return;
- }
-
- const C2PlanarLayout &layout = rView->layout();
- uint8_t *yPlane = const_cast<uint8_t *>(rView->data()[C2PlanarLayout::PLANE_Y]);
- uint8_t *uPlane = const_cast<uint8_t *>(rView->data()[C2PlanarLayout::PLANE_U]);
- uint8_t *vPlane = const_cast<uint8_t *>(rView->data()[C2PlanarLayout::PLANE_V]);
- int32_t yStride = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
- int32_t uStride = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
- int32_t vStride = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
- uint32_t width = mSize->width;
- uint32_t height = mSize->height;
- // width and height are always even (as block size is 16x16)
- CHECK_EQ((width & 1u), 0u);
- CHECK_EQ((height & 1u), 0u);
- size_t yPlaneSize = width * height;
- switch (layout.type) {
- case C2PlanarLayout::TYPE_RGB:
- [[fallthrough]];
- case C2PlanarLayout::TYPE_RGBA: {
- MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
- mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
- yPlane = conversionBuffer.data();
- uPlane = yPlane + yPlaneSize;
- vPlane = uPlane + yPlaneSize / 4;
- yStride = width;
- uStride = vStride = width / 2;
- ConvertRGBToPlanarYUV(yPlane, yStride, height, conversionBuffer.size(), *rView.get());
- break;
- }
- case C2PlanarLayout::TYPE_YUV: {
- if (!IsYUV420(*rView)) {
- ALOGE("input is not YUV420");
- work->result = C2_BAD_VALUE;
- break;
- }
-
- if (layout.planes[layout.PLANE_Y].colInc == 1
- && layout.planes[layout.PLANE_U].colInc == 1
- && layout.planes[layout.PLANE_V].colInc == 1
- && uStride == vStride
- && yStride == 2 * vStride) {
- // I420 compatible - planes are already set up above
- break;
- }
-
- // copy to I420
- MemoryBlock conversionBuffer = mConversionBuffers.fetch(yPlaneSize * 3 / 2);
- mConversionBuffersInUse.emplace(conversionBuffer.data(), conversionBuffer);
- MediaImage2 img = CreateYUV420PlanarMediaImage2(width, height, width, height);
- status_t err = ImageCopy(conversionBuffer.data(), &img, *rView);
- if (err != OK) {
- ALOGE("Buffer conversion failed: %d", err);
- work->result = C2_BAD_VALUE;
- return;
- }
- yPlane = conversionBuffer.data();
- uPlane = yPlane + yPlaneSize;
- vPlane = uPlane + yPlaneSize / 4;
- yStride = width;
- uStride = vStride = width / 2;
- break;
- }
-
- case C2PlanarLayout::TYPE_YUVA:
- ALOGE("YUVA plane type is not supported");
- work->result = C2_BAD_VALUE;
- return;
-
- default:
- ALOGE("Unrecognized plane type: %d", layout.type);
- work->result = C2_BAD_VALUE;
- return;
- }
-
- CHECK(NULL != yPlane);
- /* Encode frames */
- VideoEncFrameIO vin, vout;
- memset(&vin, 0, sizeof(vin));
- memset(&vout, 0, sizeof(vout));
- vin.yChan = yPlane;
- vin.uChan = uPlane;
- vin.vChan = vPlane;
- vin.timestamp = (inputTimeStamp + 500) / 1000; // in ms
- vin.height = align(height, 16);
- vin.pitch = align(width, 16);
-
- uint32_t modTimeMs = 0;
- int32_t nLayer = 0;
- MP4HintTrack hintTrack;
- int32_t outputSize = mOutBufferSize;
- if (!PVEncodeVideoFrame(mHandle, &vin, &vout, &modTimeMs, outPtr, &outputSize, &nLayer) ||
- !PVGetHintTrack(mHandle, &hintTrack)) {
- ALOGE("Failed to encode frame or get hint track at frame %" PRId64, mNumInputFrames);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- ALOGV("outputSize filled : %d", outputSize);
- ++mNumInputFrames;
- CHECK(NULL == PVGetOverrunBuffer(mHandle));
-
- fillEmptyWork(work);
- if (outputSize) {
- std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block, 0, outputSize);
- work->worklets.front()->output.ordinal.timestamp = inputTimeStamp;
- if (hintTrack.CodeType == 0) {
- buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
- 0u /* stream id */, C2PictureTypeKeyFrame));
- }
- work->worklets.front()->output.buffers.push_back(buffer);
- }
- if (eos) {
- mSignalledOutputEos = true;
- }
-
- mConversionBuffersInUse.erase(yPlane);
-}
-
-c2_status_t C2SoftMpeg4Enc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void)pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-class C2SoftMpeg4EncFactory : public C2ComponentFactory {
-public:
- C2SoftMpeg4EncFactory()
- : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {}
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftMpeg4Enc(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftMpeg4Enc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftMpeg4Enc::IntfImpl>(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftMpeg4Enc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftMpeg4EncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftMpeg4EncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/mpeg4_h263/C2SoftMpeg4Enc.h b/media/codecs/mpeg4_h263/C2SoftMpeg4Enc.h
deleted file mode 100644
index 43461fc..0000000
--- a/media/codecs/mpeg4_h263/C2SoftMpeg4Enc.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef C2_SOFT_MPEG4_ENC_H__
-#define C2_SOFT_MPEG4_ENC_H__
-
-#include <map>
-
-#include <Codec2BufferUtils.h>
-#include <SimpleC2Component.h>
-
-#include "mp4enc_api.h"
-
-namespace android {
-
-struct C2SoftMpeg4Enc : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftMpeg4Enc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-protected:
-
- virtual ~C2SoftMpeg4Enc();
-
-private:
- std::shared_ptr<IntfImpl> mIntf;
-
- tagvideoEncControls *mHandle;
- tagvideoEncOptions *mEncParams;
-
- bool mStarted;
- bool mSignalledOutputEos;
- bool mSignalledError;
-
- uint32_t mOutBufferSize;
- // configurations used by component in process
- // (TODO: keep this in intf but make them internal only)
- std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
- std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
- std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
-
- int64_t mNumInputFrames;
- MP4EncodingMode mEncodeMode;
-
- MemoryBlockPool mConversionBuffers;
- std::map<void *, MemoryBlock> mConversionBuffersInUse;
-
- c2_status_t initEncParams();
- c2_status_t initEncoder();
-
- C2_DO_NOT_COPY(C2SoftMpeg4Enc);
-};
-
-} // namespace android
-
-#endif // C2_SOFT_MPEG4_ENC_H__
diff --git a/media/codecs/mpeg4_h263/MODULE_LICENSE_APACHE2 b/media/codecs/mpeg4_h263/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/mpeg4_h263/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/mpeg4_h263/NOTICE b/media/codecs/mpeg4_h263/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/mpeg4_h263/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/mpeg4_h263/patent_disclaimer.txt b/media/codecs/mpeg4_h263/patent_disclaimer.txt
deleted file mode 100644
index b4bf11d..0000000
--- a/media/codecs/mpeg4_h263/patent_disclaimer.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
-THIS IS NOT A GRANT OF PATENT RIGHTS.
-
-Google makes no representation or warranty that the codecs for which
-source code is made available hereunder are unencumbered by
-third-party patents. Those intending to use this source code in
-hardware or software products are advised that implementations of
-these codecs, including in open source software or shareware, may
-require patent licenses from the relevant patent holders.
diff --git a/media/codecs/opus/Android.bp b/media/codecs/opus/Android.bp
deleted file mode 100644
index a6233a6..0000000
--- a/media/codecs/opus/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2opusdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftOpusDec.cpp"],
-
- shared_libs: ["libopus"],
-}
diff --git a/media/codecs/opus/C2SoftOpusDec.cpp b/media/codecs/opus/C2SoftOpusDec.cpp
deleted file mode 100644
index 2439c3c..0000000
--- a/media/codecs/opus/C2SoftOpusDec.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftOpusDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftOpusDec.h"
-
-extern "C" {
- #include <opus.h>
- #include <opus_multistream.h>
-}
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.opus.decoder";
-
-class C2SoftOpusDec::IntfImpl : public C2InterfaceHelper {
- public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_OPUS))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 48000))
- .withFields({C2F(mSampleRate, value).equalTo(48000)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 8)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 6000))
- .withFields({C2F(mBitrate, value).inRange(6000, 510000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 960 * 6))
- .build());
- }
-
- private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftOpusDec::C2SoftOpusDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : SimpleC2Component(
- std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mDecoder(nullptr) {
-}
-
-C2SoftOpusDec::~C2SoftOpusDec() {
- onRelease();
-}
-
-c2_status_t C2SoftOpusDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftOpusDec::onStop() {
- if (mDecoder) {
- opus_multistream_decoder_destroy(mDecoder);
- mDecoder = nullptr;
- }
- memset(&mHeader, 0, sizeof(mHeader));
- mCodecDelay = 0;
- mSeekPreRoll = 0;
- mSamplesToDiscard = 0;
- mInputBufferCount = 0;
- mSignalledError = false;
- mSignalledOutputEos = false;
-
- return C2_OK;
-}
-
-void C2SoftOpusDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftOpusDec::onRelease() {
- if (mDecoder) {
- opus_multistream_decoder_destroy(mDecoder);
- mDecoder = nullptr;
- }
-}
-
-status_t C2SoftOpusDec::initDecoder() {
- memset(&mHeader, 0, sizeof(mHeader));
- mCodecDelay = 0;
- mSeekPreRoll = 0;
- mSamplesToDiscard = 0;
- mInputBufferCount = 0;
- mSignalledError = false;
- mSignalledOutputEos = false;
-
- return OK;
-}
-
-c2_status_t C2SoftOpusDec::onFlush_sm() {
- if (mDecoder) {
- opus_multistream_decoder_ctl(mDecoder, OPUS_RESET_STATE);
- mSamplesToDiscard = mSeekPreRoll;
- mSignalledOutputEos = false;
- }
- return C2_OK;
-}
-
-c2_status_t C2SoftOpusDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-static uint16_t ReadLE16(const uint8_t *data, size_t data_size,
- uint32_t read_offset) {
- if (read_offset + 1 > data_size)
- return 0;
- uint16_t val;
- val = data[read_offset];
- val |= data[read_offset + 1] << 8;
- return val;
-}
-
-static const int kRate = 48000;
-
-// Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
-// mappings for up to 8 channels. This information is part of the Vorbis I
-// Specification:
-// http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
-static const int kMaxChannels = 8;
-
-// Maximum packet size used in Xiph's opusdec.
-static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
-
-// Default audio output channel layout. Used to initialize |stream_map| in
-// OpusHeader, and passed to opus_multistream_decoder_create() when the header
-// does not contain mapping information. The values are valid only for mono and
-// stereo output: Opus streams with more than 2 channels require a stream map.
-static const int kMaxChannelsWithDefaultLayout = 2;
-static const uint8_t kDefaultOpusChannelLayout[kMaxChannelsWithDefaultLayout] = { 0, 1 };
-
-// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
-static bool ParseOpusHeader(const uint8_t *data, size_t data_size,
- OpusHeader* header) {
- // Size of the Opus header excluding optional mapping information.
- const size_t kOpusHeaderSize = 19;
-
- // Offset to the channel count byte in the Opus header.
- const size_t kOpusHeaderChannelsOffset = 9;
-
- // Offset to the pre-skip value in the Opus header.
- const size_t kOpusHeaderSkipSamplesOffset = 10;
-
- // Offset to the gain value in the Opus header.
- const size_t kOpusHeaderGainOffset = 16;
-
- // Offset to the channel mapping byte in the Opus header.
- const size_t kOpusHeaderChannelMappingOffset = 18;
-
- // Opus Header contains a stream map. The mapping values are in the header
- // beyond the always present |kOpusHeaderSize| bytes of data. The mapping
- // data contains stream count, coupling information, and per channel mapping
- // values:
- // - Byte 0: Number of streams.
- // - Byte 1: Number coupled.
- // - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping
- // values.
- const size_t kOpusHeaderNumStreamsOffset = kOpusHeaderSize;
- const size_t kOpusHeaderNumCoupledOffset = kOpusHeaderNumStreamsOffset + 1;
- const size_t kOpusHeaderStreamMapOffset = kOpusHeaderNumStreamsOffset + 2;
-
- if (data_size < kOpusHeaderSize) {
- ALOGE("Header size is too small.");
- return false;
- }
- header->channels = *(data + kOpusHeaderChannelsOffset);
- if (header->channels <= 0 || header->channels > kMaxChannels) {
- ALOGE("Invalid Header, wrong channel count: %d", header->channels);
- return false;
- }
-
- header->skip_samples = ReadLE16(data,
- data_size,
- kOpusHeaderSkipSamplesOffset);
-
- header->gain_db = static_cast<int16_t>(ReadLE16(data,
- data_size,
- kOpusHeaderGainOffset));
-
- header->channel_mapping = *(data + kOpusHeaderChannelMappingOffset);
- if (!header->channel_mapping) {
- if (header->channels > kMaxChannelsWithDefaultLayout) {
- ALOGE("Invalid Header, missing stream map.");
- return false;
- }
- header->num_streams = 1;
- header->num_coupled = header->channels > 1;
- header->stream_map[0] = 0;
- header->stream_map[1] = 1;
- return true;
- }
- if (data_size < kOpusHeaderStreamMapOffset + header->channels) {
- ALOGE("Invalid stream map; insufficient data for current channel "
- "count: %d", header->channels);
- return false;
- }
- header->num_streams = *(data + kOpusHeaderNumStreamsOffset);
- header->num_coupled = *(data + kOpusHeaderNumCoupledOffset);
- if (header->num_streams + header->num_coupled != header->channels) {
- ALOGE("Inconsistent channel mapping.");
- return false;
- }
- for (int i = 0; i < header->channels; ++i)
- header->stream_map[i] = *(data + kOpusHeaderStreamMapOffset + i);
- return true;
-}
-
-// Convert nanoseconds to number of samples.
-static uint64_t ns_to_samples(uint64_t ns, int rate) {
- return static_cast<double>(ns) * rate / 1000000000;
-}
-
-void C2SoftOpusDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- size_t inOffset = 0u;
- size_t inSize = 0u;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
- if (inSize == 0) {
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
- const uint8_t *data = rView.data() + inOffset;
- if (mInputBufferCount < 3) {
- if (mInputBufferCount == 0) {
- if (!ParseOpusHeader(data, inSize, &mHeader)) {
- ALOGE("Encountered error while Parsing Opus Header.");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- uint8_t channel_mapping[kMaxChannels] = {0};
- if (mHeader.channels <= kMaxChannelsWithDefaultLayout) {
- memcpy(&channel_mapping,
- kDefaultOpusChannelLayout,
- kMaxChannelsWithDefaultLayout);
- } else {
- memcpy(&channel_mapping,
- mHeader.stream_map,
- mHeader.channels);
- }
- int status = OPUS_INVALID_STATE;
- mDecoder = opus_multistream_decoder_create(kRate,
- mHeader.channels,
- mHeader.num_streams,
- mHeader.num_coupled,
- channel_mapping,
- &status);
- if (!mDecoder || status != OPUS_OK) {
- ALOGE("opus_multistream_decoder_create failed status = %s",
- opus_strerror(status));
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- status = opus_multistream_decoder_ctl(mDecoder,
- OPUS_SET_GAIN(mHeader.gain_db));
- if (status != OPUS_OK) {
- ALOGE("Failed to set OPUS header gain; status = %s",
- opus_strerror(status));
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- } else {
- if (inSize < 8) {
- ALOGE("Input sample size is too small.");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- int64_t samples = ns_to_samples( *(reinterpret_cast<int64_t*>
- (const_cast<uint8_t *> (data))), kRate);
- if (mInputBufferCount == 1) {
- mCodecDelay = samples;
- mSamplesToDiscard = mCodecDelay;
- }
- else {
- mSeekPreRoll = samples;
-
- ALOGI("Configuring decoder: %d Hz, %d channels",
- kRate, mHeader.channels);
- C2StreamSampleRateInfo::output sampleRateInfo(0u, kRate);
- C2StreamChannelCountInfo::output channelCountInfo(0u, mHeader.channels);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config(
- { &sampleRateInfo, &channelCountInfo },
- C2_MAY_BLOCK,
- &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
- } else {
- ALOGE("Config Update failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- }
-
- ++mInputBufferCount;
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- // Ignore CSD re-submissions.
- if ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
- fillEmptyWork(work);
- return;
- }
-
- // When seeking to zero, |mCodecDelay| samples has to be discarded
- // instead of |mSeekPreRoll| samples (as we would when seeking to any
- // other timestamp).
- if (work->input.ordinal.timestamp.peeku() == 0) mSamplesToDiscard = mCodecDelay;
-
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(
- kMaxNumSamplesPerBuffer * kMaxChannels * sizeof(int16_t),
- usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
-
- int numSamples = opus_multistream_decode(mDecoder,
- data,
- inSize,
- reinterpret_cast<int16_t *> (wView.data()),
- kMaxOpusOutputPacketSizeSamples,
- 0);
- if (numSamples < 0) {
- ALOGE("opus_multistream_decode returned numSamples %d", numSamples);
- numSamples = 0;
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- int outOffset = 0;
- if (mSamplesToDiscard > 0) {
- if (mSamplesToDiscard > numSamples) {
- mSamplesToDiscard -= numSamples;
- numSamples = 0;
- } else {
- numSamples -= mSamplesToDiscard;
- outOffset = mSamplesToDiscard * sizeof(int16_t) * mHeader.channels;
- mSamplesToDiscard = 0;
- }
- }
-
- if (numSamples) {
- int outSize = numSamples * sizeof(int16_t) * mHeader.channels;
- ALOGV("out buffer attr. offset %d size %d ", outOffset, outSize);
-
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, outOffset, outSize));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- } else {
- fillEmptyWork(work);
- block.reset();
- }
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-class C2SoftOpusDecFactory : public C2ComponentFactory {
-public:
- C2SoftOpusDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftOpusDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftOpusDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftOpusDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftOpusDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftOpusDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftOpusDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/opus/C2SoftOpusDec.h b/media/codecs/opus/C2SoftOpusDec.h
deleted file mode 100644
index 92b7426..0000000
--- a/media/codecs/opus/C2SoftOpusDec.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_OPUS_DEC_H_
-#define ANDROID_C2_SOFT_OPUS_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-struct OpusMSDecoder;
-
-namespace android {
-
-struct OpusHeader {
- int channels;
- int skip_samples;
- int channel_mapping;
- int num_streams;
- int num_coupled;
- int16_t gain_db;
- uint8_t stream_map[8];
-};
-
-struct C2SoftOpusDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftOpusDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftOpusDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-private:
- enum {
- kMaxNumSamplesPerBuffer = 960 * 6
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- OpusMSDecoder *mDecoder;
- OpusHeader mHeader;
-
- int64_t mCodecDelay;
- int64_t mSeekPreRoll;
- int64_t mSamplesToDiscard;
- size_t mInputBufferCount;
- bool mSignalledError;
- bool mSignalledOutputEos;
-
- status_t initDecoder();
-
- C2_DO_NOT_COPY(C2SoftOpusDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_OPUS_DEC_H_
diff --git a/media/codecs/raw/Android.bp b/media/codecs/raw/Android.bp
deleted file mode 100644
index 150eb91..0000000
--- a/media/codecs/raw/Android.bp
+++ /dev/null
@@ -1,9 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2rawdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftRawDec.cpp"],
-}
diff --git a/media/codecs/raw/C2SoftRawDec.cpp b/media/codecs/raw/C2SoftRawDec.cpp
deleted file mode 100644
index 5c83481..0000000
--- a/media/codecs/raw/C2SoftRawDec.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftRawDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftRawDec.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.raw.decoder";
-
-class C2SoftRawDec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).inRange(8000, 192000)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 2))
- .withFields({C2F(mChannelCount, value).inRange(1, 8)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(1, 10000000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 64 * 1024))
- .build());
-
- addParameter(
- DefineParam(mPcmEncodingInfo, C2_PARAMKEY_PCM_ENCODING)
- .withDefault(new C2StreamPcmEncodingInfo::output(0u, C2Config::PCM_16))
- .withFields({C2F(mPcmEncodingInfo, value).oneOf({
- C2Config::PCM_16,
- C2Config::PCM_8,
- C2Config::PCM_FLOAT})
- })
- .withSetter((Setter<decltype(*mPcmEncodingInfo)>::StrictValueWithNoDeps))
- .build());
-
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
- std::shared_ptr<C2StreamPcmEncodingInfo::output> mPcmEncodingInfo;
-};
-
-C2SoftRawDec::C2SoftRawDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl) {
-}
-
-C2SoftRawDec::~C2SoftRawDec() {
- onRelease();
-}
-
-c2_status_t C2SoftRawDec::onInit() {
- mSignalledEos = false;
- return C2_OK;
-}
-
-c2_status_t C2SoftRawDec::onStop() {
- mSignalledEos = false;
- return C2_OK;
-}
-
-void C2SoftRawDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftRawDec::onRelease() {
-}
-
-c2_status_t C2SoftRawDec::onFlush_sm() {
- return onStop();
-}
-
-void C2SoftRawDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void)pool;
- work->result = C2_OK;
- work->workletsProcessed = 1u;
-
- if (mSignalledEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- ALOGV("in buffer attr. timestamp %d frameindex %d",
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
-
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- if (!work->input.buffers.empty()) {
- work->worklets.front()->output.buffers.push_back(work->input.buffers[0]);
- }
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- mSignalledEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-c2_status_t C2SoftRawDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-class C2SoftRawDecFactory : public C2ComponentFactory {
-public:
- C2SoftRawDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftRawDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftRawDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftRawDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftRawDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftRawDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftRawDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/raw/C2SoftRawDec.h b/media/codecs/raw/C2SoftRawDec.h
deleted file mode 100644
index 7dfdec5..0000000
--- a/media/codecs/raw/C2SoftRawDec.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_RAW_DEC_H_
-#define ANDROID_C2_SOFT_RAW_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-namespace android {
-
-struct C2SoftRawDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftRawDec(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftRawDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-private:
- std::shared_ptr<IntfImpl> mIntf;
- bool mSignalledEos;
-
- C2_DO_NOT_COPY(C2SoftRawDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_RAW_DEC_H_
diff --git a/media/codecs/raw/MODULE_LICENSE_APACHE2 b/media/codecs/raw/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/raw/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/raw/NOTICE b/media/codecs/raw/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/raw/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/vorbis/Android.bp b/media/codecs/vorbis/Android.bp
deleted file mode 100644
index 7477da6..0000000
--- a/media/codecs/vorbis/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2vorbisdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftVorbisDec.cpp"],
-
- shared_libs: ["libvorbisidec"],
-}
diff --git a/media/codecs/vorbis/C2SoftVorbisDec.cpp b/media/codecs/vorbis/C2SoftVorbisDec.cpp
deleted file mode 100644
index 280ae36..0000000
--- a/media/codecs/vorbis/C2SoftVorbisDec.cpp
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftVorbisDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftVorbisDec.h"
-
-extern "C" {
- #include <Tremolo/codec_internal.h>
-
- int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
- int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
- int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
-}
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.vorbis.decoder";
-
-class C2SoftVorbisDec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_VORBIS))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 48000))
- .withFields({C2F(mSampleRate, value).inRange(8000, 96000)})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 8)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(32000, 500000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192 * 2 * sizeof(int16_t)))
- .build());
- }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
-};
-
-C2SoftVorbisDec::C2SoftVorbisDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mState(nullptr),
- mVi(nullptr) {
-}
-
-C2SoftVorbisDec::~C2SoftVorbisDec() {
- onRelease();
-}
-
-c2_status_t C2SoftVorbisDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_NO_MEMORY;
-}
-
-c2_status_t C2SoftVorbisDec::onStop() {
- if (mState) {
- vorbis_dsp_clear(mState);
- delete mState;
- mState = nullptr;
- }
-
- if (mVi) {
- vorbis_info_clear(mVi);
- delete mVi;
- mVi = nullptr;
- }
- mNumFramesLeftOnPage = -1;
- mSignalledOutputEos = false;
- mSignalledError = false;
-
- return (initDecoder() == OK ? C2_OK : C2_CORRUPTED);
-}
-
-void C2SoftVorbisDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftVorbisDec::onRelease() {
- if (mState) {
- vorbis_dsp_clear(mState);
- delete mState;
- mState = nullptr;
- }
-
- if (mVi) {
- vorbis_info_clear(mVi);
- delete mVi;
- mVi = nullptr;
- }
-}
-
-status_t C2SoftVorbisDec::initDecoder() {
- mVi = new vorbis_info{};
- if (!mVi) return NO_MEMORY;
- vorbis_info_clear(mVi);
-
- mState = new vorbis_dsp_state{};
- if (!mState) return NO_MEMORY;
- vorbis_dsp_clear(mState);
-
- mNumFramesLeftOnPage = -1;
- mSignalledError = false;
- mSignalledOutputEos = false;
- mInfoUnpacked = false;
- mBooksUnpacked = false;
- return OK;
-}
-
-c2_status_t C2SoftVorbisDec::onFlush_sm() {
- mNumFramesLeftOnPage = -1;
- mSignalledOutputEos = false;
- if (mState) vorbis_dsp_restart(mState);
-
- return C2_OK;
-}
-
-c2_status_t C2SoftVorbisDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void) pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-static void makeBitReader(
- const void *data, size_t size,
- ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
- buf->data = (uint8_t *)data;
- buf->size = size;
- buf->refcount = 1;
- buf->ptr.owner = nullptr;
-
- ref->buffer = buf;
- ref->begin = 0;
- ref->length = size;
- ref->next = nullptr;
-
- oggpack_readinit(bits, ref);
-}
-
-// (CHECK!) multiframe is tricky. decode call doesnt return the number of bytes
-// consumed by the component. Also it is unclear why numPageFrames is being
-// tagged at the end of input buffers for new pages. Refer lines 297-300 in
-// SimpleDecodingSource.cpp
-void C2SoftVorbisDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- size_t inOffset = 0u;
- size_t inSize = 0u;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = rView.error();
- return;
- }
- }
-
- if (inSize == 0) {
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d", inSize,
- (int)work->input.ordinal.timestamp.peeku(), (int)work->input.ordinal.frameIndex.peeku());
- const uint8_t *data = rView.data() + inOffset;
- int32_t numChannels = mVi->channels;
- int32_t samplingRate = mVi->rate;
- if (inSize > 7 && !memcmp(&data[1], "vorbis", 6)) {
- if ((data[0] != 1) && (data[0] != 5)) {
- ALOGE("unexpected type received %d", data[0]);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- ogg_buffer buf;
- ogg_reference ref;
- oggpack_buffer bits;
-
- // skip 7 <type + "vorbis"> bytes
- makeBitReader((const uint8_t *)data + 7, inSize - 7, &buf, &ref, &bits);
- if (data[0] == 1) {
- vorbis_info_init(mVi);
- if (0 != _vorbis_unpack_info(mVi, &bits)) {
- ALOGE("Encountered error while unpacking info");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- if (mVi->rate != samplingRate ||
- mVi->channels != numChannels) {
- ALOGV("vorbis: rate/channels changed: %ld/%d", mVi->rate, mVi->channels);
- samplingRate = mVi->rate;
- numChannels = mVi->channels;
-
- C2StreamSampleRateInfo::output sampleRateInfo(0u, samplingRate);
- C2StreamChannelCountInfo::output channelCountInfo(0u, numChannels);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config(
- { &sampleRateInfo, &channelCountInfo },
- C2_MAY_BLOCK,
- &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(sampleRateInfo));
- work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(channelCountInfo));
- } else {
- ALOGE("Config Update failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- mInfoUnpacked = true;
- } else {
- if (!mInfoUnpacked) {
- ALOGE("Data with type:5 sent before sending type:1");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- if (0 != _vorbis_unpack_books(mVi, &bits)) {
- ALOGE("Encountered error while unpacking books");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- if (0 != vorbis_dsp_init(mState, mVi)) {
- ALOGE("Encountered error while dsp init");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- mBooksUnpacked = true;
- }
- fillEmptyWork(work);
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- return;
- }
-
- if (!mInfoUnpacked || !mBooksUnpacked) {
- ALOGE("Missing CODEC_CONFIG data mInfoUnpacked: %d mBooksUnpack %d", mInfoUnpacked, mBooksUnpacked);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- int32_t numPageFrames = 0;
- if (inSize < sizeof(numPageFrames)) {
- ALOGE("input header has size %zu, expected %zu", inSize, sizeof(numPageFrames));
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- memcpy(&numPageFrames, data + inSize - sizeof(numPageFrames), sizeof(numPageFrames));
- inSize -= sizeof(numPageFrames);
- if (numPageFrames >= 0) {
- mNumFramesLeftOnPage = numPageFrames;
- }
-
- ogg_buffer buf;
- buf.data = const_cast<unsigned char*>(data);
- buf.size = inSize;
- buf.refcount = 1;
- buf.ptr.owner = nullptr;
-
- ogg_reference ref;
- ref.buffer = &buf;
- ref.begin = 0;
- ref.length = buf.size;
- ref.next = nullptr;
-
- ogg_packet pack;
- pack.packet = &ref;
- pack.bytes = ref.length;
- pack.b_o_s = 0;
- pack.e_o_s = 0;
- pack.granulepos = 0;
- pack.packetno = 0;
-
- size_t maxSamplesInBuffer = kMaxNumSamplesPerChannel * mVi->channels;
- size_t outCapacity = maxSamplesInBuffer * sizeof(int16_t);
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(outCapacity, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = wView.error();
- return;
- }
-
- int numFrames = 0;
- int ret = vorbis_dsp_synthesis(mState, &pack, 1);
- if (0 != ret) {
- ALOGE("vorbis_dsp_synthesis returned %d", ret);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- } else {
- numFrames = vorbis_dsp_pcmout(
- mState, reinterpret_cast<int16_t *> (wView.data()),
- kMaxNumSamplesPerChannel);
- if (numFrames < 0) {
- ALOGD("vorbis_dsp_pcmout returned %d", numFrames);
- numFrames = 0;
- }
- }
-
- if (mNumFramesLeftOnPage >= 0) {
- if (numFrames > mNumFramesLeftOnPage) {
- ALOGV("discarding %d frames at end of page", numFrames - mNumFramesLeftOnPage);
- numFrames = mNumFramesLeftOnPage;
- }
- mNumFramesLeftOnPage -= numFrames;
- }
-
- if (numFrames) {
- int outSize = numFrames * sizeof(int16_t) * mVi->channels;
-
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(createLinearBuffer(block, 0, outSize));
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- } else {
- fillEmptyWork(work);
- block.reset();
- }
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
-}
-
-class C2SoftVorbisDecFactory : public C2ComponentFactory {
-public:
- C2SoftVorbisDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftVorbisDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftVorbisDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftVorbisDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftVorbisDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftVorbisDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftVorbisDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/vorbis/C2SoftVorbisDec.h b/media/codecs/vorbis/C2SoftVorbisDec.h
deleted file mode 100644
index 3bf7326..0000000
--- a/media/codecs/vorbis/C2SoftVorbisDec.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_VORBIS_DEC_H_
-#define ANDROID_C2_SOFT_VORBIS_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-struct vorbis_dsp_state;
-struct vorbis_info;
-
-namespace android {
-
-struct C2SoftVorbisDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftVorbisDec(const char *name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl);
- virtual ~C2SoftVorbisDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
- private:
- enum {
- kMaxNumSamplesPerChannel = 8192,
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- vorbis_dsp_state *mState;
- vorbis_info *mVi;
-
- int32_t mNumFramesLeftOnPage;
- bool mSignalledError;
- bool mSignalledOutputEos;
- bool mInfoUnpacked;
- bool mBooksUnpacked;
- status_t initDecoder();
-
- C2_DO_NOT_COPY(C2SoftVorbisDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_VORBIS_DEC_H_
-
diff --git a/media/codecs/vorbis/MODULE_LICENSE_APACHE2 b/media/codecs/vorbis/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/vorbis/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/vorbis/NOTICE b/media/codecs/vorbis/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/codecs/vorbis/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/vpx/Android.bp b/media/codecs/vpx/Android.bp
deleted file mode 100644
index cc83371..0000000
--- a/media/codecs/vpx/Android.bp
+++ /dev/null
@@ -1,60 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2vp9dec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftVpxDec.cpp"],
-
- shared_libs: ["libvpx"],
-
- cflags: [
- "-DVP9",
- ],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2vp8dec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftVpxDec.cpp"],
-
- shared_libs: ["libvpx"],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2vp9enc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: [
- "C2SoftVp9Enc.cpp",
- "C2SoftVpxEnc.cpp",
- ],
-
- shared_libs: ["libvpx"],
-
- cflags: ["-DVP9"],
-}
-
-cc_library_shared {
- name: "libstagefright_soft_c2vp8enc",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: [
- "C2SoftVp8Enc.cpp",
- "C2SoftVpxEnc.cpp",
- ],
-
- shared_libs: ["libvpx"],
-}
-
diff --git a/media/codecs/vpx/C2SoftVp8Enc.cpp b/media/codecs/vpx/C2SoftVp8Enc.cpp
deleted file mode 100644
index 0ae717a..0000000
--- a/media/codecs/vpx/C2SoftVp8Enc.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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 "C2SoftVp8Enc"
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include "C2SoftVp8Enc.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.vp8.encoder";
-
-C2SoftVp8Enc::C2SoftVp8Enc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : C2SoftVpxEnc(name, id, intfImpl), mDCTPartitions(0), mProfile(1) {}
-
-void C2SoftVp8Enc::setCodecSpecificInterface() {
- mCodecInterface = vpx_codec_vp8_cx();
-}
-
-void C2SoftVp8Enc::setCodecSpecificConfiguration() {
- switch (mProfile) {
- case 1:
- mCodecConfiguration->g_profile = 0;
- break;
-
- case 2:
- mCodecConfiguration->g_profile = 1;
- break;
-
- case 4:
- mCodecConfiguration->g_profile = 2;
- break;
-
- case 8:
- mCodecConfiguration->g_profile = 3;
- break;
-
- default:
- mCodecConfiguration->g_profile = 0;
- }
-}
-
-vpx_codec_err_t C2SoftVp8Enc::setCodecSpecificControls() {
- vpx_codec_err_t codec_return = vpx_codec_control(mCodecContext,
- VP8E_SET_TOKEN_PARTITIONS,
- mDCTPartitions);
- if (codec_return != VPX_CODEC_OK) {
- ALOGE("Error setting dct partitions for vpx encoder.");
- }
- return codec_return;
-}
-
-class C2SoftVp8EncFactory : public C2ComponentFactory {
-public:
- C2SoftVp8EncFactory()
- : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {}
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftVp8Enc(COMPONENT_NAME, id,
- std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftVpxEnc::IntfImpl>(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftVp8EncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftVp8EncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/vpx/C2SoftVp8Enc.h b/media/codecs/vpx/C2SoftVp8Enc.h
deleted file mode 100644
index ed6f356..0000000
--- a/media/codecs/vpx/C2SoftVp8Enc.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_C2_SOFT_VP8_ENC_H__
-#define ANDROID_C2_SOFT_VP8_ENC_H__
-
-#include "C2SoftVpxEnc.h"
-
-namespace android {
-
-// Exposes vp8 encoder as a c2 Component
-//
-// In addition to the base class settings, Only following encoder settings are
-// available:
-// - token partitioning
-struct C2SoftVp8Enc : public C2SoftVpxEnc {
- C2SoftVp8Enc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
-
- protected:
- // Populates |mCodecInterface| with codec specific settings.
- virtual void setCodecSpecificInterface();
-
- // Sets codec specific configuration.
- virtual void setCodecSpecificConfiguration();
-
- // Initializes codec specific encoder settings.
- virtual vpx_codec_err_t setCodecSpecificControls();
-
- private:
- // Max value supported for DCT partitions
- static const uint32_t kMaxDCTPartitions = 3;
-
- // vp8 specific configuration parameter
- // that enables token partitioning of
- // the stream into substreams
- int32_t mDCTPartitions;
-
- // C2 Profile parameter
- int32_t mProfile;
-
- C2_DO_NOT_COPY(C2SoftVp8Enc);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_VP8_ENC_H__
diff --git a/media/codecs/vpx/C2SoftVp9Enc.cpp b/media/codecs/vpx/C2SoftVp9Enc.cpp
deleted file mode 100644
index b26170f..0000000
--- a/media/codecs/vpx/C2SoftVp9Enc.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 "C2SoftVp9Enc"
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include "C2SoftVp9Enc.h"
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.vp9.encoder";
-
-C2SoftVp9Enc::C2SoftVp9Enc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : C2SoftVpxEnc(name, id, intfImpl),
- mProfile(1),
- mLevel(0),
- mTileColumns(0),
- mFrameParallelDecoding(false) {
-}
-
-void C2SoftVp9Enc::setCodecSpecificInterface() {
- mCodecInterface = vpx_codec_vp9_cx();
-}
-
-void C2SoftVp9Enc::setCodecSpecificConfiguration() {
- switch (mProfile) {
- case 1:
- mCodecConfiguration->g_profile = 0;
- break;
-
- case 2:
- mCodecConfiguration->g_profile = 1;
- break;
-
- case 4:
- mCodecConfiguration->g_profile = 2;
- break;
-
- case 8:
- mCodecConfiguration->g_profile = 3;
- break;
-
- default:
- mCodecConfiguration->g_profile = 0;
- }
-}
-
-vpx_codec_err_t C2SoftVp9Enc::setCodecSpecificControls() {
- vpx_codec_err_t codecReturn = vpx_codec_control(
- mCodecContext, VP9E_SET_TILE_COLUMNS, mTileColumns);
- if (codecReturn != VPX_CODEC_OK) {
- ALOGE("Error setting VP9E_SET_TILE_COLUMNS to %d. vpx_codec_control() "
- "returned %d", mTileColumns, codecReturn);
- return codecReturn;
- }
- codecReturn = vpx_codec_control(
- mCodecContext, VP9E_SET_FRAME_PARALLEL_DECODING,
- mFrameParallelDecoding);
- if (codecReturn != VPX_CODEC_OK) {
- ALOGE("Error setting VP9E_SET_FRAME_PARALLEL_DECODING to %d."
- "vpx_codec_control() returned %d", mFrameParallelDecoding,
- codecReturn);
- return codecReturn;
- }
- codecReturn = vpx_codec_control(mCodecContext, VP9E_SET_ROW_MT, 1);
- if (codecReturn != VPX_CODEC_OK) {
- ALOGE("Error setting VP9E_SET_ROW_MT to 1. vpx_codec_control() "
- "returned %d", codecReturn);
- return codecReturn;
- }
-
- // For VP9, we always set CPU_USED to 8 (because the realtime default is 0
- // which is too slow).
- codecReturn = vpx_codec_control(mCodecContext, VP8E_SET_CPUUSED, 8);
- if (codecReturn != VPX_CODEC_OK) {
- ALOGE("Error setting VP8E_SET_CPUUSED to 8. vpx_codec_control() "
- "returned %d", codecReturn);
- return codecReturn;
- }
- return codecReturn;
-}
-
-class C2SoftVp9EncFactory : public C2ComponentFactory {
-public:
- C2SoftVp9EncFactory()
- : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {}
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftVp9Enc(COMPONENT_NAME, id,
- std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftVpxEnc::IntfImpl>(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftVpxEnc::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftVp9EncFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftVp9EncFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/vpx/C2SoftVp9Enc.h b/media/codecs/vpx/C2SoftVp9Enc.h
deleted file mode 100644
index 77ef8fd..0000000
--- a/media/codecs/vpx/C2SoftVp9Enc.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_C2_SOFT_VP9_ENC_H__
-#define ANDROID_C2_SOFT_VP9_ENC_H__
-
-#include "C2SoftVpxEnc.h"
-
-namespace android {
-
-// Exposes vp9 encoder as a c2 Component
-//
-// In addition to the base class settings, Only following encoder settings are
-// available:
-// - tile rows
-// - tile columns
-// - frame parallel mode
-struct C2SoftVp9Enc : public C2SoftVpxEnc {
- C2SoftVp9Enc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
-
- protected:
- // Populates |mCodecInterface| with codec specific settings.
- virtual void setCodecSpecificInterface();
-
- // Sets codec specific configuration.
- virtual void setCodecSpecificConfiguration();
-
- // Initializes codec specific encoder settings.
- virtual vpx_codec_err_t setCodecSpecificControls();
-
- private:
- // C2 Profile & Level parameter
- int32_t mProfile;
- int32_t mLevel __unused;
-
- int32_t mTileColumns;
-
- bool mFrameParallelDecoding;
-
- C2_DO_NOT_COPY(C2SoftVp9Enc);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_VP9_ENC_H__
diff --git a/media/codecs/vpx/C2SoftVpxDec.cpp b/media/codecs/vpx/C2SoftVpxDec.cpp
deleted file mode 100644
index 8ecbf5d..0000000
--- a/media/codecs/vpx/C2SoftVpxDec.cpp
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftVpxDec"
-#include <log/log.h>
-
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftVpxDec.h"
-
-namespace android {
-
-#ifdef VP9
-constexpr char COMPONENT_NAME[] = "c2.android.vp9.decoder";
-#else
-constexpr char COMPONENT_NAME[] = "c2.android.vp8.decoder";
-#endif
-
-class C2SoftVpxDec::IntfImpl : public SimpleInterface<void>::BaseParams {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : SimpleInterface<void>::BaseParams(
- helper,
- COMPONENT_NAME,
- C2Component::KIND_DECODER,
- C2Component::DOMAIN_VIDEO,
-#ifdef VP9
- MEDIA_MIMETYPE_VIDEO_VP9
-#else
- MEDIA_MIMETYPE_VIDEO_VP8
-#endif
- ) {
- noPrivateBuffers(); // TODO: account for our buffers here
- noInputReferences();
- noOutputReferences();
- noInputLatency();
- noTimeStretch();
-
- // TODO: output latency and reordering
-
- addParameter(
- DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES)
- .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE)
- .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
- })
- .withSetter(SizeSetter)
- .build());
-
-#ifdef VP9
- // TODO: Add C2Config::PROFILE_VP9_2HDR ??
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_VP9_0, C2Config::LEVEL_VP9_5))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_VP9_0,
- C2Config::PROFILE_VP9_2}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_VP9_1,
- C2Config::LEVEL_VP9_1_1,
- C2Config::LEVEL_VP9_2,
- C2Config::LEVEL_VP9_2_1,
- C2Config::LEVEL_VP9_3,
- C2Config::LEVEL_VP9_3_1,
- C2Config::LEVEL_VP9_4,
- C2Config::LEVEL_VP9_4_1,
- C2Config::LEVEL_VP9_5,
- })
- })
- .withSetter(ProfileLevelSetter, mSize)
- .build());
-
- mHdr10PlusInfoInput = C2StreamHdr10PlusInfo::input::AllocShared(0);
- addParameter(
- DefineParam(mHdr10PlusInfoInput, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO)
- .withDefault(mHdr10PlusInfoInput)
- .withFields({
- C2F(mHdr10PlusInfoInput, m.value).any(),
- })
- .withSetter(Hdr10PlusInfoInputSetter)
- .build());
-
- mHdr10PlusInfoOutput = C2StreamHdr10PlusInfo::output::AllocShared(0);
- addParameter(
- DefineParam(mHdr10PlusInfoOutput, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO)
- .withDefault(mHdr10PlusInfoOutput)
- .withFields({
- C2F(mHdr10PlusInfoOutput, m.value).any(),
- })
- .withSetter(Hdr10PlusInfoOutputSetter)
- .build());
-
-#if 0
- // sample BT.2020 static info
- mHdrStaticInfo = std::make_shared<C2StreamHdrStaticInfo::output>();
- mHdrStaticInfo->mastering = {
- .red = { .x = 0.708, .y = 0.292 },
- .green = { .x = 0.170, .y = 0.797 },
- .blue = { .x = 0.131, .y = 0.046 },
- .white = { .x = 0.3127, .y = 0.3290 },
- .maxLuminance = 1000,
- .minLuminance = 0.1,
- };
- mHdrStaticInfo->maxCll = 1000;
- mHdrStaticInfo->maxFall = 120;
-
- mHdrStaticInfo->maxLuminance = 0; // disable static info
-
- helper->addStructDescriptors<C2MasteringDisplayColorVolumeStruct, C2ColorXyStruct>();
- addParameter(
- DefineParam(mHdrStaticInfo, C2_PARAMKEY_HDR_STATIC_INFO)
- .withDefault(mHdrStaticInfo)
- .withFields({
- C2F(mHdrStaticInfo, mastering.red.x).inRange(0, 1),
- // TODO
- })
- .withSetter(HdrStaticInfoSetter)
- .build());
-#endif
-#else
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withConstValue(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_UNUSED, C2Config::LEVEL_UNUSED))
- .build());
-#endif
-
- addParameter(
- DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
- .withDefault(new C2StreamMaxPictureSizeTuning::output(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
- })
- .withSetter(MaxPictureSizeSetter, mSize)
- .build());
-
- addParameter(
- DefineParam(mMaxInputSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withDefault(new C2StreamMaxBufferSizeInfo::input(0u, 320 * 240 * 3 / 4))
- .withFields({
- C2F(mMaxInputSize, value).any(),
- })
- .calculatedAs(MaxInputSizeSetter, mMaxSize)
- .build());
-
- C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() };
- std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- 1u, 0u, 8u /* bitDepth */, C2Color::YUV_420);
- memcpy(defaultColorInfo->m.locations, locations, sizeof(locations));
-
- defaultColorInfo =
- C2StreamColorInfo::output::AllocShared(
- { C2ChromaOffsetStruct::ITU_YUV_420_0() },
- 0u, 8u /* bitDepth */, C2Color::YUV_420);
- helper->addStructDescriptors<C2ChromaOffsetStruct>();
-
- addParameter(
- DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO)
- .withConstValue(defaultColorInfo)
- .build());
-
- // TODO: support more formats?
- addParameter(
- DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT)
- .withConstValue(new C2StreamPixelFormatInfo::output(
- 0u, HAL_PIXEL_FORMAT_YCBCR_420_888))
- .build());
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output> &oldMe,
- C2P<C2VideoSizeStreamInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R MaxPictureSizeSetter(bool mayBlock, C2P<C2StreamMaxPictureSizeTuning::output> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- // TODO: get max width/height from the size's field helpers vs. hardcoding
- me.set().width = c2_min(c2_max(me.v.width, size.v.width), 2048u);
- me.set().height = c2_min(c2_max(me.v.height, size.v.height), 2048u);
- return C2R::Ok();
- }
-
- static C2R MaxInputSizeSetter(bool mayBlock, C2P<C2StreamMaxBufferSizeInfo::input> &me,
- const C2P<C2StreamMaxPictureSizeTuning::output> &maxSize) {
- (void)mayBlock;
- // assume compression ratio of 2
- me.set().value = (((maxSize.v.width + 63) / 64) * ((maxSize.v.height + 63) / 64) * 3072);
- return C2R::Ok();
- }
-
-
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me,
- const C2P<C2StreamPictureSizeInfo::output> &size) {
- (void)mayBlock;
- (void)size;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) {
- (void)mayBlock;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
- static C2R Hdr10PlusInfoOutputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::output> &me) {
- (void)mayBlock;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
-
-private:
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
- std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mMaxInputSize;
- std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
- std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
-#ifdef VP9
-#if 0
- std::shared_ptr<C2StreamHdrStaticInfo::output> mHdrStaticInfo;
-#endif
- std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
- std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
-#endif
-};
-
-C2SoftVpxDec::C2SoftVpxDec(
- const char *name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mCodecCtx(nullptr) {
-}
-
-C2SoftVpxDec::~C2SoftVpxDec() {
- onRelease();
-}
-
-c2_status_t C2SoftVpxDec::onInit() {
- status_t err = initDecoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-c2_status_t C2SoftVpxDec::onStop() {
- mSignalledError = false;
- mSignalledOutputEos = false;
-
- return C2_OK;
-}
-
-void C2SoftVpxDec::onReset() {
- (void)onStop();
- c2_status_t err = onFlush_sm();
- if (err != C2_OK)
- {
- ALOGW("Failed to flush decoder. Try to hard reset decoder");
- destroyDecoder();
- (void)initDecoder();
- }
-}
-
-void C2SoftVpxDec::onRelease() {
- destroyDecoder();
-}
-
-c2_status_t C2SoftVpxDec::onFlush_sm() {
- if (mFrameParallelMode) {
- // Flush decoder by passing nullptr data ptr and 0 size.
- // Ideally, this should never fail.
- if (vpx_codec_decode(mCodecCtx, nullptr, 0, nullptr, 0)) {
- ALOGE("Failed to flush on2 decoder.");
- return C2_CORRUPTED;
- }
- }
-
- // Drop all the decoded frames in decoder.
- vpx_codec_iter_t iter = nullptr;
- while (vpx_codec_get_frame(mCodecCtx, &iter)) {
- }
-
- mSignalledError = false;
- mSignalledOutputEos = false;
- return C2_OK;
-}
-
-static int GetCPUCoreCount() {
- int cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
- cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- // _SC_NPROC_ONLN must be defined...
- cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
- CHECK(cpuCoreCount >= 1);
- ALOGV("Number of CPU cores: %d", cpuCoreCount);
- return cpuCoreCount;
-}
-
-status_t C2SoftVpxDec::initDecoder() {
-#ifdef VP9
- mMode = MODE_VP9;
-#else
- mMode = MODE_VP8;
-#endif
-
- mWidth = 320;
- mHeight = 240;
- mFrameParallelMode = false;
- mSignalledOutputEos = false;
- mSignalledError = false;
-
- if (!mCodecCtx) {
- mCodecCtx = new vpx_codec_ctx_t;
- }
- if (!mCodecCtx) {
- ALOGE("mCodecCtx is null");
- return NO_MEMORY;
- }
-
- vpx_codec_dec_cfg_t cfg;
- memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
- cfg.threads = GetCPUCoreCount();
-
- vpx_codec_flags_t flags;
- memset(&flags, 0, sizeof(vpx_codec_flags_t));
- if (mFrameParallelMode) flags |= VPX_CODEC_USE_FRAME_THREADING;
-
- vpx_codec_err_t vpx_err;
- if ((vpx_err = vpx_codec_dec_init(
- mCodecCtx, mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo,
- &cfg, flags))) {
- ALOGE("on2 decoder failed to initialize. (%d)", vpx_err);
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2SoftVpxDec::destroyDecoder() {
- if (mCodecCtx) {
- vpx_codec_destroy(mCodecCtx);
- delete mCodecCtx;
- mCodecCtx = nullptr;
- }
-
- return OK;
-}
-
-void fillEmptyWork(const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftVpxDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2GraphicBlock> &block) {
- std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block,
- C2Rect(mWidth, mHeight));
- auto fillWork = [buffer, index, intf = this->mIntf](
- const std::unique_ptr<C2Work> &work) {
- uint32_t flags = 0;
- if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
- (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-
- for (const std::unique_ptr<C2Param> &param: work->input.configUpdate) {
- if (param) {
- C2StreamHdr10PlusInfo::input *hdr10PlusInfo =
- C2StreamHdr10PlusInfo::input::From(param.get());
-
- if (hdr10PlusInfo != nullptr) {
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- std::unique_ptr<C2Param> outParam = C2Param::CopyAsStream(
- *param.get(), true /*output*/, param->stream());
- c2_status_t err = intf->config(
- { outParam.get() }, C2_MAY_BLOCK, &failures);
- if (err == C2_OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(*outParam.get()));
- } else {
- ALOGE("finishWork: Config update size failed");
- }
- break;
- }
- }
- }
- };
- if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
- fillWork(work);
- } else {
- finish(index, fillWork);
- }
-}
-
-void C2SoftVpxDec::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 0u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
-
- size_t inOffset = 0u;
- size_t inSize = 0u;
- C2ReadView rView = mDummyReadView;
- if (!work->input.buffers.empty()) {
- rView = work->input.buffers[0]->data().linearBlocks().front().map().get();
- inSize = rView.capacity();
- if (inSize && rView.error()) {
- ALOGE("read view map failed %d", rView.error());
- work->result = C2_CORRUPTED;
- return;
- }
- }
-
- bool codecConfig = ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) !=0);
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
-
- ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x",
- inSize, (int)work->input.ordinal.timestamp.peeku(),
- (int)work->input.ordinal.frameIndex.peeku(), work->input.flags);
-
- // Software VP9 Decoder does not need the Codec Specific Data (CSD)
- // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if
- // it was passed.
- if (codecConfig) {
- // Ignore CSD buffer for VP9.
- if (mMode == MODE_VP9) {
- fillEmptyWork(work);
- return;
- } else {
- // Tolerate the CSD buffer for VP8. This is a workaround
- // for b/28689536. continue
- ALOGW("WARNING: Got CSD buffer for VP8. Continue");
- }
- }
-
- int64_t frameIndex = work->input.ordinal.frameIndex.peekll();
-
- if (inSize) {
- uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
- vpx_codec_err_t err = vpx_codec_decode(
- mCodecCtx, bitstream, inSize, &frameIndex, 0);
- if (err != VPX_CODEC_OK) {
- ALOGE("on2 decoder failed to decode frame. err: %d", err);
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return;
- }
- }
-
- (void)outputBuffer(pool, work);
-
- if (eos) {
- drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work);
- mSignalledOutputEos = true;
- } else if (!inSize) {
- fillEmptyWork(work);
- }
-}
-
-static void copyOutputBufferToYV12Frame(uint8_t *dst,
- const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
- size_t srcYStride, size_t srcUStride, size_t srcVStride,
- uint32_t width, uint32_t height, int32_t bpp) {
- size_t dstYStride = align(width, 16) * bpp ;
- size_t dstUVStride = align(dstYStride / 2, 16);
- uint8_t *dstStart = dst;
-
- for (size_t i = 0; i < height; ++i) {
- memcpy(dst, srcY, width * bpp);
- srcY += srcYStride;
- dst += dstYStride;
- }
-
- dst = dstStart + dstYStride * height;
- for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcV, width / 2 * bpp);
- srcV += srcVStride;
- dst += dstUVStride;
- }
-
- dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2);
- for (size_t i = 0; i < height / 2; ++i) {
- memcpy(dst, srcU, width / 2 * bpp);
- srcU += srcUStride;
- dst += dstUVStride;
- }
-}
-
-bool C2SoftVpxDec::outputBuffer(
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work)
-{
- if (!(work && pool)) return false;
-
- vpx_codec_iter_t iter = nullptr;
- vpx_image_t *img = vpx_codec_get_frame(mCodecCtx, &iter);
-
- if (!img) return false;
-
- if (img->d_w != mWidth || img->d_h != mHeight) {
- mWidth = img->d_w;
- mHeight = img->d_h;
-
- C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures);
- if (err == C2_OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(size));
- } else {
- ALOGE("Config update size failed");
- mSignalledError = true;
- work->workletsProcessed = 1u;
- work->result = C2_CORRUPTED;
- return false;
- }
-
- }
- CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016);
- int32_t bpp = 1;
- if (img->fmt == VPX_IMG_FMT_I42016) {
- bpp = 2;
- }
-
- std::shared_ptr<C2GraphicBlock> block;
- uint32_t format = HAL_PIXEL_FORMAT_YV12;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16) * bpp, mHeight, format, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchGraphicBlock for Output failed with status %d", err);
- work->result = err;
- return false;
- }
-
- C2GraphicView wView = block->map().get();
- if (wView.error()) {
- ALOGE("graphic view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return false;
- }
-
- ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d",
- block->width(), block->height(), mWidth, mHeight, (int)*(int64_t *)img->user_priv);
-
- uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]);
- size_t srcYStride = img->stride[VPX_PLANE_Y];
- size_t srcUStride = img->stride[VPX_PLANE_U];
- size_t srcVStride = img->stride[VPX_PLANE_V];
- const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y];
- const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U];
- const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V];
- copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV,
- srcYStride, srcUStride, srcVStride, mWidth, mHeight, bpp);
-
- finishWork(*(int64_t *)img->user_priv, work, std::move(block));
- return true;
-}
-
-c2_status_t C2SoftVpxDec::drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work) {
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- while ((outputBuffer(pool, work))) {
- }
-
- if (drainMode == DRAIN_COMPONENT_WITH_EOS &&
- work && work->workletsProcessed == 0u) {
- fillEmptyWork(work);
- }
-
- return C2_OK;
-}
-c2_status_t C2SoftVpxDec::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- return drainInternal(drainMode, pool, nullptr);
-}
-
-class C2SoftVpxFactory : public C2ComponentFactory {
-public:
- C2SoftVpxFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftVpxDec(COMPONENT_NAME, id,
- std::make_shared<C2SoftVpxDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftVpxDec::IntfImpl>(
- COMPONENT_NAME, id,
- std::make_shared<C2SoftVpxDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftVpxFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftVpxFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/vpx/C2SoftVpxDec.h b/media/codecs/vpx/C2SoftVpxDec.h
deleted file mode 100644
index 60c8484..0000000
--- a/media/codecs/vpx/C2SoftVpxDec.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_VPX_DEC_H_
-#define ANDROID_C2_SOFT_VPX_DEC_H_
-
-#include <SimpleC2Component.h>
-
-
-#include "vpx/vpx_decoder.h"
-#include "vpx/vp8dx.h"
-
-namespace android {
-
-struct C2SoftVpxDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftVpxDec(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftVpxDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
- private:
- enum {
- MODE_VP8,
- MODE_VP9,
- } mMode;
-
- std::shared_ptr<IntfImpl> mIntf;
- vpx_codec_ctx_t *mCodecCtx;
- bool mFrameParallelMode; // Frame parallel is only supported by VP9 decoder.
-
- uint32_t mWidth;
- uint32_t mHeight;
- bool mSignalledOutputEos;
- bool mSignalledError;
-
- status_t initDecoder();
- status_t destroyDecoder();
- void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2GraphicBlock> &block);
- bool outputBuffer(
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work);
- c2_status_t drainInternal(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool,
- const std::unique_ptr<C2Work> &work);
-
- C2_DO_NOT_COPY(C2SoftVpxDec);
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_VPX_DEC_H_
diff --git a/media/codecs/vpx/C2SoftVpxEnc.cpp b/media/codecs/vpx/C2SoftVpxEnc.cpp
deleted file mode 100644
index 155a84f..0000000
--- a/media/codecs/vpx/C2SoftVpxEnc.cpp
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * 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 "C2SoftVpxEnc"
-#include <log/log.h>
-#include <utils/misc.h>
-
-#include <media/hardware/VideoAPI.h>
-
-#include <Codec2BufferUtils.h>
-#include <C2Debug.h>
-#include "C2SoftVpxEnc.h"
-
-#ifndef INT32_MAX
-#define INT32_MAX 2147483647
-#endif
-
-namespace android {
-
-#if 0
-static size_t getCpuCoreCount() {
- long cpuCoreCount = 1;
-#if defined(_SC_NPROCESSORS_ONLN)
- cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- // _SC_NPROC_ONLN must be defined...
- cpuCoreCount = sysconf(_SC_NPROC_ONLN);
-#endif
- CHECK(cpuCoreCount >= 1);
- ALOGV("Number of CPU cores: %ld", cpuCoreCount);
- return (size_t)cpuCoreCount;
-}
-#endif
-
-C2SoftVpxEnc::C2SoftVpxEnc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl)
- : SimpleC2Component(
- std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mCodecContext(nullptr),
- mCodecConfiguration(nullptr),
- mCodecInterface(nullptr),
- mStrideAlign(2),
- mColorFormat(VPX_IMG_FMT_I420),
- mBitrateControlMode(VPX_VBR),
- mErrorResilience(false),
- mMinQuantizer(0),
- mMaxQuantizer(0),
- mTemporalLayers(0),
- mTemporalPatternType(VPXTemporalLayerPatternNone),
- mTemporalPatternLength(0),
- mTemporalPatternIdx(0),
- mLastTimestamp(0x7FFFFFFFFFFFFFFFull),
- mSignalledOutputEos(false),
- mSignalledError(false) {
- memset(mTemporalLayerBitrateRatio, 0, sizeof(mTemporalLayerBitrateRatio));
- mTemporalLayerBitrateRatio[0] = 100;
-}
-
-C2SoftVpxEnc::~C2SoftVpxEnc() {
- onRelease();
-}
-
-c2_status_t C2SoftVpxEnc::onInit() {
- status_t err = initEncoder();
- return err == OK ? C2_OK : C2_CORRUPTED;
-}
-
-void C2SoftVpxEnc::onRelease() {
- if (mCodecContext) {
- vpx_codec_destroy(mCodecContext);
- delete mCodecContext;
- mCodecContext = nullptr;
- }
-
- if (mCodecConfiguration) {
- delete mCodecConfiguration;
- mCodecConfiguration = nullptr;
- }
-
- // this one is not allocated by us
- mCodecInterface = nullptr;
-}
-
-c2_status_t C2SoftVpxEnc::onStop() {
- onRelease();
- mLastTimestamp = 0x7FFFFFFFFFFFFFFFLL;
- mSignalledOutputEos = false;
- mSignalledError = false;
- return C2_OK;
-}
-
-void C2SoftVpxEnc::onReset() {
- (void)onStop();
-}
-
-c2_status_t C2SoftVpxEnc::onFlush_sm() {
- return onStop();
-}
-
-status_t C2SoftVpxEnc::initEncoder() {
- vpx_codec_err_t codec_return;
- status_t result = UNKNOWN_ERROR;
- {
- IntfImpl::Lock lock = mIntf->lock();
- mSize = mIntf->getSize_l();
- mBitrate = mIntf->getBitrate_l();
- mBitrateMode = mIntf->getBitrateMode_l();
- mFrameRate = mIntf->getFrameRate_l();
- mIntraRefresh = mIntf->getIntraRefresh_l();
- mRequestSync = mIntf->getRequestSync_l();
- mTemporalLayers = mIntf->getTemporalLayers_l()->m.layerCount;
- }
-
- switch (mBitrateMode->value) {
- case C2Config::BITRATE_VARIABLE:
- mBitrateControlMode = VPX_VBR;
- break;
- case C2Config::BITRATE_CONST:
- default:
- mBitrateControlMode = VPX_CBR;
- break;
- break;
- }
-
- setCodecSpecificInterface();
- if (!mCodecInterface) goto CleanUp;
-
- ALOGD("VPx: initEncoder. BRMode: %u. TSLayers: %zu. KF: %u. QP: %u - %u",
- (uint32_t)mBitrateControlMode, mTemporalLayers, mIntf->getSyncFramePeriod(),
- mMinQuantizer, mMaxQuantizer);
-
- mCodecConfiguration = new vpx_codec_enc_cfg_t;
- if (!mCodecConfiguration) goto CleanUp;
- codec_return = vpx_codec_enc_config_default(mCodecInterface,
- mCodecConfiguration,
- 0);
- if (codec_return != VPX_CODEC_OK) {
- ALOGE("Error populating default configuration for vpx encoder.");
- goto CleanUp;
- }
-
- mCodecConfiguration->g_w = mSize->width;
- mCodecConfiguration->g_h = mSize->height;
- //mCodecConfiguration->g_threads = getCpuCoreCount();
- mCodecConfiguration->g_threads = 0;
- mCodecConfiguration->g_error_resilient = mErrorResilience;
-
- // timebase unit is microsecond
- // g_timebase is in seconds (i.e. 1/1000000 seconds)
- mCodecConfiguration->g_timebase.num = 1;
- mCodecConfiguration->g_timebase.den = 1000000;
- // rc_target_bitrate is in kbps, mBitrate in bps
- mCodecConfiguration->rc_target_bitrate = (mBitrate->value + 500) / 1000;
- mCodecConfiguration->rc_end_usage = mBitrateControlMode;
- // Disable frame drop - not allowed in MediaCodec now.
- mCodecConfiguration->rc_dropframe_thresh = 0;
- // Disable lagged encoding.
- mCodecConfiguration->g_lag_in_frames = 0;
- if (mBitrateControlMode == VPX_CBR) {
- // Disable spatial resizing.
- mCodecConfiguration->rc_resize_allowed = 0;
- // Single-pass mode.
- mCodecConfiguration->g_pass = VPX_RC_ONE_PASS;
- // Maximum amount of bits that can be subtracted from the target
- // bitrate - expressed as percentage of the target bitrate.
- mCodecConfiguration->rc_undershoot_pct = 100;
- // Maximum amount of bits that can be added to the target
- // bitrate - expressed as percentage of the target bitrate.
- mCodecConfiguration->rc_overshoot_pct = 15;
- // Initial value of the buffer level in ms.
- mCodecConfiguration->rc_buf_initial_sz = 500;
- // Amount of data that the encoder should try to maintain in ms.
- mCodecConfiguration->rc_buf_optimal_sz = 600;
- // The amount of data that may be buffered by the decoding
- // application in ms.
- mCodecConfiguration->rc_buf_sz = 1000;
- // Enable error resilience - needed for packet loss.
- mCodecConfiguration->g_error_resilient = 1;
- // Maximum key frame interval - for CBR boost to 3000
- mCodecConfiguration->kf_max_dist = 3000;
- // Encoder determines optimal key frame placement automatically.
- mCodecConfiguration->kf_mode = VPX_KF_AUTO;
- }
-
- // Frames temporal pattern - for now WebRTC like pattern is only supported.
- switch (mTemporalLayers) {
- case 0:
- mTemporalPatternLength = 0;
- break;
- case 1:
- mCodecConfiguration->ts_number_layers = 1;
- mCodecConfiguration->ts_rate_decimator[0] = 1;
- mCodecConfiguration->ts_periodicity = 1;
- mCodecConfiguration->ts_layer_id[0] = 0;
- mTemporalPattern[0] = kTemporalUpdateLastRefAll;
- mTemporalPatternLength = 1;
- break;
- case 2:
- mCodecConfiguration->ts_number_layers = 2;
- mCodecConfiguration->ts_rate_decimator[0] = 2;
- mCodecConfiguration->ts_rate_decimator[1] = 1;
- mCodecConfiguration->ts_periodicity = 2;
- mCodecConfiguration->ts_layer_id[0] = 0;
- mCodecConfiguration->ts_layer_id[1] = 1;
- mTemporalPattern[0] = kTemporalUpdateLastAndGoldenRefAltRef;
- mTemporalPattern[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
- mTemporalPattern[2] = kTemporalUpdateLastRefAltRef;
- mTemporalPattern[3] = kTemporalUpdateGoldenRefAltRef;
- mTemporalPattern[4] = kTemporalUpdateLastRefAltRef;
- mTemporalPattern[5] = kTemporalUpdateGoldenRefAltRef;
- mTemporalPattern[6] = kTemporalUpdateLastRefAltRef;
- mTemporalPattern[7] = kTemporalUpdateNone;
- mTemporalPatternLength = 8;
- break;
- case 3:
- mCodecConfiguration->ts_number_layers = 3;
- mCodecConfiguration->ts_rate_decimator[0] = 4;
- mCodecConfiguration->ts_rate_decimator[1] = 2;
- mCodecConfiguration->ts_rate_decimator[2] = 1;
- mCodecConfiguration->ts_periodicity = 4;
- mCodecConfiguration->ts_layer_id[0] = 0;
- mCodecConfiguration->ts_layer_id[1] = 2;
- mCodecConfiguration->ts_layer_id[2] = 1;
- mCodecConfiguration->ts_layer_id[3] = 2;
- mTemporalPattern[0] = kTemporalUpdateLastAndGoldenRefAltRef;
- mTemporalPattern[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef;
- mTemporalPattern[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
- mTemporalPattern[3] = kTemporalUpdateNone;
- mTemporalPattern[4] = kTemporalUpdateLastRefAltRef;
- mTemporalPattern[5] = kTemporalUpdateNone;
- mTemporalPattern[6] = kTemporalUpdateGoldenRefAltRef;
- mTemporalPattern[7] = kTemporalUpdateNone;
- mTemporalPatternLength = 8;
- break;
- default:
- ALOGE("Wrong number of temporal layers %zu", mTemporalLayers);
- goto CleanUp;
- }
- // Set bitrate values for each layer
- for (size_t i = 0; i < mCodecConfiguration->ts_number_layers; i++) {
- mCodecConfiguration->ts_target_bitrate[i] =
- mCodecConfiguration->rc_target_bitrate *
- mTemporalLayerBitrateRatio[i] / 100;
- }
- if (mIntf->getSyncFramePeriod() >= 0) {
- mCodecConfiguration->kf_max_dist = mIntf->getSyncFramePeriod();
- mCodecConfiguration->kf_min_dist = mIntf->getSyncFramePeriod();
- mCodecConfiguration->kf_mode = VPX_KF_AUTO;
- }
- if (mMinQuantizer > 0) {
- mCodecConfiguration->rc_min_quantizer = mMinQuantizer;
- }
- if (mMaxQuantizer > 0) {
- mCodecConfiguration->rc_max_quantizer = mMaxQuantizer;
- }
- setCodecSpecificConfiguration();
- mCodecContext = new vpx_codec_ctx_t;
- if (!mCodecContext) goto CleanUp;
- codec_return = vpx_codec_enc_init(mCodecContext,
- mCodecInterface,
- mCodecConfiguration,
- 0); // flags
- if (codec_return != VPX_CODEC_OK) {
- ALOGE("Error initializing vpx encoder");
- goto CleanUp;
- }
-
- // Extra CBR settings
- if (mBitrateControlMode == VPX_CBR) {
- codec_return = vpx_codec_control(mCodecContext,
- VP8E_SET_STATIC_THRESHOLD,
- 1);
- if (codec_return == VPX_CODEC_OK) {
- uint32_t rc_max_intra_target =
- (uint32_t)(mCodecConfiguration->rc_buf_optimal_sz * mFrameRate->value / 20 + 0.5);
- // Don't go below 3 times per frame bandwidth.
- if (rc_max_intra_target < 300) {
- rc_max_intra_target = 300;
- }
- codec_return = vpx_codec_control(mCodecContext,
- VP8E_SET_MAX_INTRA_BITRATE_PCT,
- rc_max_intra_target);
- }
- if (codec_return == VPX_CODEC_OK) {
- codec_return = vpx_codec_control(mCodecContext,
- VP8E_SET_CPUUSED,
- -8);
- }
- if (codec_return != VPX_CODEC_OK) {
- ALOGE("Error setting cbr parameters for vpx encoder.");
- goto CleanUp;
- }
- }
-
- codec_return = setCodecSpecificControls();
- if (codec_return != VPX_CODEC_OK) goto CleanUp;
-
- {
- uint32_t width = mSize->width;
- uint32_t height = mSize->height;
- if (((uint64_t)width * height) >
- ((uint64_t)INT32_MAX / 3)) {
- ALOGE("b/25812794, Buffer size is too big, width=%u, height=%u.", width, height);
- } else {
- uint32_t stride = (width + mStrideAlign - 1) & ~(mStrideAlign - 1);
- uint32_t vstride = (height + mStrideAlign - 1) & ~(mStrideAlign - 1);
- mConversionBuffer = MemoryBlock::Allocate(stride * vstride * 3 / 2);
- if (!mConversionBuffer.size()) {
- ALOGE("Allocating conversion buffer failed.");
- } else {
- mNumInputFrames = -1;
- return OK;
- }
- }
- }
-
-CleanUp:
- onRelease();
- return result;
-}
-
-vpx_enc_frame_flags_t C2SoftVpxEnc::getEncodeFlags() {
- vpx_enc_frame_flags_t flags = 0;
- if (mTemporalPatternLength > 0) {
- int patternIdx = mTemporalPatternIdx % mTemporalPatternLength;
- mTemporalPatternIdx++;
- switch (mTemporalPattern[patternIdx]) {
- case kTemporalUpdateLast:
- flags |= VP8_EFLAG_NO_UPD_GF;
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_REF_GF;
- flags |= VP8_EFLAG_NO_REF_ARF;
- break;
- case kTemporalUpdateGoldenWithoutDependency:
- flags |= VP8_EFLAG_NO_REF_GF;
- [[fallthrough]];
- case kTemporalUpdateGolden:
- flags |= VP8_EFLAG_NO_REF_ARF;
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_UPD_LAST;
- break;
- case kTemporalUpdateAltrefWithoutDependency:
- flags |= VP8_EFLAG_NO_REF_ARF;
- flags |= VP8_EFLAG_NO_REF_GF;
- [[fallthrough]];
- case kTemporalUpdateAltref:
- flags |= VP8_EFLAG_NO_UPD_GF;
- flags |= VP8_EFLAG_NO_UPD_LAST;
- break;
- case kTemporalUpdateNoneNoRefAltref:
- flags |= VP8_EFLAG_NO_REF_ARF;
- [[fallthrough]];
- case kTemporalUpdateNone:
- flags |= VP8_EFLAG_NO_UPD_GF;
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_UPD_LAST;
- flags |= VP8_EFLAG_NO_UPD_ENTROPY;
- break;
- case kTemporalUpdateNoneNoRefGoldenRefAltRef:
- flags |= VP8_EFLAG_NO_REF_GF;
- flags |= VP8_EFLAG_NO_UPD_GF;
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_UPD_LAST;
- flags |= VP8_EFLAG_NO_UPD_ENTROPY;
- break;
- case kTemporalUpdateGoldenWithoutDependencyRefAltRef:
- flags |= VP8_EFLAG_NO_REF_GF;
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_UPD_LAST;
- break;
- case kTemporalUpdateLastRefAltRef:
- flags |= VP8_EFLAG_NO_UPD_GF;
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_REF_GF;
- break;
- case kTemporalUpdateGoldenRefAltRef:
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_UPD_LAST;
- break;
- case kTemporalUpdateLastAndGoldenRefAltRef:
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_REF_GF;
- break;
- case kTemporalUpdateLastRefAll:
- flags |= VP8_EFLAG_NO_UPD_ARF;
- flags |= VP8_EFLAG_NO_UPD_GF;
- break;
- }
- }
- return flags;
-}
-
-// TODO: add support for YUV input color formats
-// TODO: add support for SVC, ARF. SVC and ARF returns multiple frames
-// (hierarchical / noshow) in one call. These frames should be combined in to
-// a single buffer and sent back to the client
-void C2SoftVpxEnc::process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
- // Initialize encoder if not already
- if (!mCodecContext && OK != initEncoder()) {
- ALOGE("Failed to initialize encoder");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- std::shared_ptr<const C2GraphicView> rView;
- std::shared_ptr<C2Buffer> inputBuffer;
- if (!work->input.buffers.empty()) {
- inputBuffer = work->input.buffers[0];
- rView = std::make_shared<const C2GraphicView>(
- inputBuffer->data().graphicBlocks().front().map().get());
- if (rView->error() != C2_OK) {
- ALOGE("graphic view map err = %d", rView->error());
- work->result = C2_CORRUPTED;
- return;
- }
- } else {
- ALOGV("Empty input Buffer");
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- return;
- }
-
- const C2ConstGraphicBlock inBuffer =
- inputBuffer->data().graphicBlocks().front();
- if (inBuffer.width() != mSize->width ||
- inBuffer.height() != mSize->height) {
- ALOGE("unexpected Input buffer attributes %d(%d) x %d(%d)",
- inBuffer.width(), mSize->width, inBuffer.height(),
- mSize->height);
- mSignalledError = true;
- work->result = C2_BAD_VALUE;
- return;
- }
- bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0);
- vpx_image_t raw_frame;
- const C2PlanarLayout &layout = rView->layout();
- uint32_t width = rView->width();
- uint32_t height = rView->height();
- if (width > 0x8000 || height > 0x8000) {
- ALOGE("Image too big: %u x %u", width, height);
- work->result = C2_BAD_VALUE;
- return;
- }
- uint32_t stride = (width + mStrideAlign - 1) & ~(mStrideAlign - 1);
- uint32_t vstride = (height + mStrideAlign - 1) & ~(mStrideAlign - 1);
- switch (layout.type) {
- case C2PlanarLayout::TYPE_RGB:
- case C2PlanarLayout::TYPE_RGBA: {
- ConvertRGBToPlanarYUV(mConversionBuffer.data(), stride, vstride,
- mConversionBuffer.size(), *rView.get());
- vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, width, height,
- mStrideAlign, mConversionBuffer.data());
- break;
- }
- case C2PlanarLayout::TYPE_YUV: {
- if (!IsYUV420(*rView)) {
- ALOGE("input is not YUV420");
- work->result = C2_BAD_VALUE;
- return;
- }
-
- if (layout.planes[layout.PLANE_Y].colInc == 1
- && layout.planes[layout.PLANE_U].colInc == 1
- && layout.planes[layout.PLANE_V].colInc == 1) {
- // I420 compatible - though with custom offset and stride
- vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, width, height,
- mStrideAlign, (uint8_t*)rView->data()[0]);
- raw_frame.planes[1] = (uint8_t*)rView->data()[1];
- raw_frame.planes[2] = (uint8_t*)rView->data()[2];
- raw_frame.stride[0] = layout.planes[layout.PLANE_Y].rowInc;
- raw_frame.stride[1] = layout.planes[layout.PLANE_U].rowInc;
- raw_frame.stride[2] = layout.planes[layout.PLANE_V].rowInc;
- } else {
- // copy to I420
- MediaImage2 img = CreateYUV420PlanarMediaImage2(width, height, stride, vstride);
- if (mConversionBuffer.size() >= stride * vstride * 3 / 2) {
- status_t err = ImageCopy(mConversionBuffer.data(), &img, *rView);
- if (err != OK) {
- ALOGE("Buffer conversion failed: %d", err);
- work->result = C2_BAD_VALUE;
- return;
- }
- vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, stride, vstride,
- mStrideAlign, (uint8_t*)rView->data()[0]);
- vpx_img_set_rect(&raw_frame, 0, 0, width, height);
- } else {
- ALOGE("Conversion buffer is too small: %u x %u for %zu",
- stride, vstride, mConversionBuffer.size());
- work->result = C2_BAD_VALUE;
- return;
- }
- }
- break;
- }
- default:
- ALOGE("Unrecognized plane type: %d", layout.type);
- work->result = C2_BAD_VALUE;
- return;
- }
-
- vpx_enc_frame_flags_t flags = getEncodeFlags();
- // handle dynamic config parameters
- {
- IntfImpl::Lock lock = mIntf->lock();
- std::shared_ptr<C2StreamIntraRefreshTuning::output> intraRefresh = mIntf->getIntraRefresh_l();
- std::shared_ptr<C2StreamBitrateInfo::output> bitrate = mIntf->getBitrate_l();
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> requestSync = mIntf->getRequestSync_l();
- lock.unlock();
-
- if (intraRefresh != mIntraRefresh) {
- mIntraRefresh = intraRefresh;
- ALOGV("Got mIntraRefresh request");
- }
-
- if (requestSync != mRequestSync) {
- // we can handle IDR immediately
- if (requestSync->value) {
- // unset request
- C2StreamRequestSyncFrameTuning::output clearSync(0u, C2_FALSE);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- mIntf->config({ &clearSync }, C2_MAY_BLOCK, &failures);
- ALOGV("Got sync request");
- flags |= VPX_EFLAG_FORCE_KF;
- }
- mRequestSync = requestSync;
- }
-
- if (bitrate != mBitrate) {
- mBitrate = bitrate;
- mCodecConfiguration->rc_target_bitrate =
- (mBitrate->value + 500) / 1000;
- vpx_codec_err_t res = vpx_codec_enc_config_set(mCodecContext,
- mCodecConfiguration);
- if (res != VPX_CODEC_OK) {
- ALOGE("vpx encoder failed to update bitrate: %s",
- vpx_codec_err_to_string(res));
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- }
-
- uint64_t inputTimeStamp = work->input.ordinal.timestamp.peekull();
- uint32_t frameDuration;
- if (inputTimeStamp > mLastTimestamp) {
- frameDuration = (uint32_t)(inputTimeStamp - mLastTimestamp);
- } else {
- // Use default of 30 fps in case of 0 frame rate.
- float frameRate = mFrameRate->value;
- if (frameRate < 0.001) {
- frameRate = 30;
- }
- frameDuration = (uint32_t)(1000000 / frameRate + 0.5);
- }
- mLastTimestamp = inputTimeStamp;
-
- vpx_codec_err_t codec_return = vpx_codec_encode(mCodecContext, &raw_frame,
- inputTimeStamp,
- frameDuration, flags,
- VPX_DL_REALTIME);
- if (codec_return != VPX_CODEC_OK) {
- ALOGE("vpx encoder failed to encode frame");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- bool populated = false;
- vpx_codec_iter_t encoded_packet_iterator = nullptr;
- const vpx_codec_cx_pkt_t* encoded_packet;
- while ((encoded_packet = vpx_codec_get_cx_data(
- mCodecContext, &encoded_packet_iterator))) {
- if (encoded_packet->kind == VPX_CODEC_CX_FRAME_PKT) {
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- c2_status_t err = pool->fetchLinearBlock(encoded_packet->data.frame.sz, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock for Output failed with status %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- if (wView.error()) {
- ALOGE("write view map failed %d", wView.error());
- work->result = C2_CORRUPTED;
- return;
- }
-
- memcpy(wView.data(), encoded_packet->data.frame.buf, encoded_packet->data.frame.sz);
- ++mNumInputFrames;
-
- ALOGD("bytes generated %zu", encoded_packet->data.frame.sz);
- uint32_t flags = 0;
- if (eos) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block);
- if (encoded_packet->data.frame.flags & VPX_FRAME_IS_KEY) {
- buffer->setInfo(std::make_shared<C2StreamPictureTypeMaskInfo::output>(
- 0u /* stream id */, C2PictureTypeKeyFrame));
- }
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->worklets.front()->output.ordinal.timestamp = encoded_packet->data.frame.pts;
- work->workletsProcessed = 1u;
- populated = true;
- if (eos) {
- mSignalledOutputEos = true;
- ALOGV("signalled EOS");
- }
- }
- }
- if (!populated) {
- work->workletsProcessed = 0u;
- }
-}
-
-c2_status_t C2SoftVpxEnc::drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) {
- (void)pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-} // namespace android
diff --git a/media/codecs/vpx/C2SoftVpxEnc.h b/media/codecs/vpx/C2SoftVpxEnc.h
deleted file mode 100644
index 87ed1a9..0000000
--- a/media/codecs/vpx/C2SoftVpxEnc.h
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_C2_SOFT_VPX_ENC_H__
-#define ANDROID_C2_SOFT_VPX_ENC_H__
-
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <C2PlatformSupport.h>
-#include <Codec2BufferUtils.h>
-#include <SimpleC2Component.h>
-#include <SimpleC2Interface.h>
-#include <util/C2InterfaceHelper.h>
-
-#include "vpx/vpx_encoder.h"
-#include "vpx/vpx_codec.h"
-#include "vpx/vpx_image.h"
-#include "vpx/vp8cx.h"
-
-namespace android {
-
-// TODO: These defs taken from deprecated OMX_VideoExt.h. Move these definitions
-// to a new header file and include it.
-
-/** Maximum number of temporal layers */
-#define MAXTEMPORALLAYERS 3
-
-/** temporal layer patterns */
-typedef enum TemporalPatternType {
- VPXTemporalLayerPatternNone = 0,
- VPXTemporalLayerPatternWebRTC = 1,
- VPXTemporalLayerPatternMax = 0x7FFFFFFF
-} TemporalPatternType;
-
-// Base class for a VPX Encoder Component
-//
-// Only following encoder settings are available (codec specific settings might
-// be available in the sub-classes):
-// - video resolution
-// - target bitrate
-// - rate control (constant / variable)
-// - frame rate
-// - error resilience
-// - reconstruction & loop filters (g_profile)
-//
-// Only following color formats are recognized
-// - C2PlanarLayout::TYPE_RGB
-// - C2PlanarLayout::TYPE_RGBA
-//
-// Following settings are not configurable by the client
-// - encoding deadline is realtime
-// - multithreaded encoding utilizes a number of threads equal
-// to online cpu's available
-// - the algorithm interface for encoder is decided by the sub-class in use
-// - fractional bits of frame rate is discarded
-// - timestamps are in microseconds, therefore encoder timebase is fixed
-// to 1/1000000
-
-struct C2SoftVpxEnc : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftVpxEnc(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
-
- // From SimpleC2Component
- c2_status_t onInit() override final;
- c2_status_t onStop() override final;
- void onReset() override final;
- void onRelease() override final;
- c2_status_t onFlush_sm() override final;
-
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override final;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override final;
-
- protected:
- std::shared_ptr<IntfImpl> mIntf;
- virtual ~C2SoftVpxEnc();
-
- // Initializes vpx encoder with available settings.
- status_t initEncoder();
-
- // Populates mCodecInterface with codec specific settings.
- virtual void setCodecSpecificInterface() = 0;
-
- // Sets codec specific configuration.
- virtual void setCodecSpecificConfiguration() = 0;
-
- // Sets codec specific encoder controls.
- virtual vpx_codec_err_t setCodecSpecificControls() = 0;
-
- // Get current encode flags.
- virtual vpx_enc_frame_flags_t getEncodeFlags();
-
- enum TemporalReferences {
- // For 1 layer case: reference all (last, golden, and alt ref), but only
- // update last.
- kTemporalUpdateLastRefAll = 12,
- // First base layer frame for 3 temporal layers, which updates last and
- // golden with alt ref dependency.
- kTemporalUpdateLastAndGoldenRefAltRef = 11,
- // First enhancement layer with alt ref dependency.
- kTemporalUpdateGoldenRefAltRef = 10,
- // First enhancement layer with alt ref dependency.
- kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
- // Base layer with alt ref dependency.
- kTemporalUpdateLastRefAltRef = 8,
- // Highest enhacement layer without dependency on golden with alt ref
- // dependency.
- kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
- // Second layer and last frame in cycle, for 2 layers.
- kTemporalUpdateNoneNoRefAltref = 6,
- // Highest enhancement layer.
- kTemporalUpdateNone = 5,
- // Second enhancement layer.
- kTemporalUpdateAltref = 4,
- // Second enhancement layer without dependency on previous frames in
- // the second enhancement layer.
- kTemporalUpdateAltrefWithoutDependency = 3,
- // First enhancement layer.
- kTemporalUpdateGolden = 2,
- // First enhancement layer without dependency on previous frames in
- // the first enhancement layer.
- kTemporalUpdateGoldenWithoutDependency = 1,
- // Base layer.
- kTemporalUpdateLast = 0,
- };
- enum {
- kMaxTemporalPattern = 8
- };
-
- // vpx specific opaque data structure that
- // stores encoder state
- vpx_codec_ctx_t* mCodecContext;
-
- // vpx specific data structure that
- // stores encoder configuration
- vpx_codec_enc_cfg_t* mCodecConfiguration;
-
- // vpx specific read-only data structure
- // that specifies algorithm interface (e.g. vp8)
- vpx_codec_iface_t* mCodecInterface;
-
- // align stride to the power of 2
- int32_t mStrideAlign;
-
- // Color format for the input port
- vpx_img_fmt_t mColorFormat;
-
- // Bitrate control mode, either constant or variable
- vpx_rc_mode mBitrateControlMode;
-
- // Parameter that denotes whether error resilience
- // is enabled in encoder
- bool mErrorResilience;
-
- // Minimum (best quality) quantizer
- uint32_t mMinQuantizer;
-
- // Maximum (worst quality) quantizer
- uint32_t mMaxQuantizer;
-
- // Number of coding temporal layers to be used.
- size_t mTemporalLayers;
-
- // Temporal layer bitrare ratio in percentage
- uint32_t mTemporalLayerBitrateRatio[MAXTEMPORALLAYERS];
-
- // Temporal pattern type
- TemporalPatternType mTemporalPatternType;
-
- // Temporal pattern length
- size_t mTemporalPatternLength;
-
- // Temporal pattern current index
- size_t mTemporalPatternIdx;
-
- // Frame type temporal pattern
- TemporalReferences mTemporalPattern[kMaxTemporalPattern];
-
- // Last input buffer timestamp
- uint64_t mLastTimestamp;
-
- // Number of input frames
- int64_t mNumInputFrames;
-
- // Conversion buffer is needed to input to
- // yuv420 planar format.
- MemoryBlock mConversionBuffer;
-
- // Signalled EOS
- bool mSignalledOutputEos;
-
- // Signalled Error
- bool mSignalledError;
-
- // configurations used by component in process
- // (TODO: keep this in intf but make them internal only)
- std::shared_ptr<C2StreamPictureSizeInfo::input> mSize;
- std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
- std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
- std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
- std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
-
- C2_DO_NOT_COPY(C2SoftVpxEnc);
-};
-
-class C2SoftVpxEnc::IntfImpl : public C2InterfaceHelper {
- public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper)
- : C2InterfaceHelper(helper) {
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::input(0u, C2FormatVideo))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(
- new C2StreamFormatConfig::output(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_VIDEO_RAW))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
-#ifdef VP9
- MEDIA_MIMETYPE_VIDEO_VP9
-#else
- MEDIA_MIMETYPE_VIDEO_VP8
-#endif
- ))
- .build());
-
- addParameter(DefineParam(mUsage, C2_NAME_INPUT_STREAM_USAGE_SETTING)
- .withConstValue(new C2StreamUsageTuning::input(
- 0u, (uint64_t)C2MemoryUsage::CPU_READ))
- .build());
-
- addParameter(
- DefineParam(mSize, C2_NAME_STREAM_VIDEO_SIZE_SETTING)
- .withDefault(new C2VideoSizeStreamTuning::input(0u, 320, 240))
- .withFields({
- C2F(mSize, width).inRange(2, 2048, 2),
- C2F(mSize, height).inRange(2, 2048, 2),
- })
- .withSetter(SizeSetter)
- .build());
-
- addParameter(
- DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
- .withDefault(new C2StreamBitrateModeTuning::output(
- 0u, C2Config::BITRATE_CONST))
- .withFields({
- C2F(mBitrateMode, value).oneOf({
- C2Config::BITRATE_CONST, C2Config::BITRATE_VARIABLE })
- })
- .withSetter(
- Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mFrameRate, C2_NAME_STREAM_FRAME_RATE_SETTING)
- .withDefault(new C2StreamFrameRateInfo::output(0u, 30.))
- // TODO: More restriction?
- .withFields({C2F(mFrameRate, value).greaterThan(0.)})
- .withSetter(
- Setter<decltype(*mFrameRate)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mLayering, C2_PARAMKEY_TEMPORAL_LAYERING)
- .withDefault(C2StreamTemporalLayeringTuning::output::AllocShared(0u, 0, 0, 0))
- .withFields({
- C2F(mLayering, m.layerCount).inRange(0, 4),
- C2F(mLayering, m.bLayerCount).inRange(0, 0),
- C2F(mLayering, m.bitrateRatios).inRange(0., 1.)
- })
- .withSetter(LayeringSetter)
- .build());
-
- addParameter(
- DefineParam(mSyncFramePeriod, C2_PARAMKEY_SYNC_FRAME_INTERVAL)
- .withDefault(new C2StreamSyncFrameIntervalTuning::output(0u, 1000000))
- .withFields({C2F(mSyncFramePeriod, value).any()})
- .withSetter(Setter<decltype(*mSyncFramePeriod)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::output(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(4096, 40000000)})
- .withSetter(BitrateSetter)
- .build());
-
- addParameter(
- DefineParam(mIntraRefresh, C2_PARAMKEY_INTRA_REFRESH)
- .withConstValue(new C2StreamIntraRefreshTuning::output(
- 0u, C2Config::INTRA_REFRESH_DISABLED, 0.))
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::output(
- 0u, PROFILE_VP9_0, LEVEL_VP9_4_1))
- .withFields({
- C2F(mProfileLevel, profile).equalTo(
- PROFILE_VP9_0
- ),
- C2F(mProfileLevel, level).equalTo(
- LEVEL_VP9_4_1),
- })
- .withSetter(ProfileLevelSetter)
- .build());
-
- addParameter(
- DefineParam(mRequestSync, C2_PARAMKEY_REQUEST_SYNC_FRAME)
- .withDefault(new C2StreamRequestSyncFrameTuning::output(0u, C2_FALSE))
- .withFields({C2F(mRequestSync, value).oneOf({ C2_FALSE, C2_TRUE }) })
- .withSetter(Setter<decltype(*mRequestSync)>::NonStrictValueWithNoDeps)
- .build());
- }
-
- static C2R BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.value <= 4096) {
- me.set().value = 4096;
- }
- return res;
- }
-
- static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::input> &oldMe,
- C2P<C2StreamPictureSizeInfo::input> &me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (!me.F(me.v.width).supportsAtAll(me.v.width)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width)));
- me.set().width = oldMe.v.width;
- }
- if (!me.F(me.v.height).supportsAtAll(me.v.height)) {
- res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height)));
- me.set().height = oldMe.v.height;
- }
- return res;
- }
-
- static C2R ProfileLevelSetter(
- bool mayBlock,
- C2P<C2StreamProfileLevelInfo::output> &me) {
- (void)mayBlock;
- if (!me.F(me.v.profile).supportsAtAll(me.v.profile)) {
- me.set().profile = PROFILE_VP9_0;
- }
- if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
- me.set().level = LEVEL_VP9_4_1;
- }
- return C2R::Ok();
- }
-
- static C2R LayeringSetter(bool mayBlock, C2P<C2StreamTemporalLayeringTuning::output>& me) {
- (void)mayBlock;
- C2R res = C2R::Ok();
- if (me.v.m.layerCount > 4) {
- me.set().m.layerCount = 4;
- }
- me.set().m.bLayerCount = 0;
- // ensure ratios are monotonic and clamped between 0 and 1
- for (size_t ix = 0; ix < me.v.flexCount(); ++ix) {
- me.set().m.bitrateRatios[ix] = c2_clamp(
- ix > 0 ? me.v.m.bitrateRatios[ix - 1] : 0, me.v.m.bitrateRatios[ix], 1.);
- }
- ALOGI("setting temporal layering %u + %u", me.v.m.layerCount, me.v.m.bLayerCount);
- return res;
- }
-
- // unsafe getters
- std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
- std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
- std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
- std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
- std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const { return mBitrateMode; }
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
- std::shared_ptr<C2StreamTemporalLayeringTuning::output> getTemporalLayers_l() const { return mLayering; }
- uint32_t getSyncFramePeriod() const {
- if (mSyncFramePeriod->value < 0 || mSyncFramePeriod->value == INT64_MAX) {
- return 0;
- }
- double period = mSyncFramePeriod->value / 1e6 * mFrameRate->value;
- return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
- }
-
- private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamUsageTuning::input> mUsage;
- std::shared_ptr<C2VideoSizeStreamTuning::input> mSize;
- std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
- std::shared_ptr<C2StreamTemporalLayeringTuning::output> mLayering;
- std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
- std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
- std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
- std::shared_ptr<C2BitrateTuning::output> mBitrate;
- std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
- std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
-};
-
-} // namespace android
-
-#endif // ANDROID_C2_SOFT_VPX_ENC_H__
diff --git a/media/codecs/vpx/MODULE_LICENSE_APACHE2 b/media/codecs/vpx/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/codecs/vpx/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/codecs/vpx/NOTICE b/media/codecs/vpx/NOTICE
deleted file mode 100644
index faed58a..0000000
--- a/media/codecs/vpx/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2013, 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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/media/codecs/xaac/Android.bp b/media/codecs/xaac/Android.bp
deleted file mode 100644
index 19c12cf..0000000
--- a/media/codecs/xaac/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-cc_library_shared {
- name: "libstagefright_soft_c2xaacdec",
- defaults: [
- "libstagefright_soft_c2-defaults",
- "libstagefright_soft_c2_sanitize_all-defaults",
- ],
-
- srcs: ["C2SoftXaacDec.cpp"],
-
- static_libs: ["libxaacdec"],
-}
diff --git a/media/codecs/xaac/C2SoftXaacDec.cpp b/media/codecs/xaac/C2SoftXaacDec.cpp
deleted file mode 100644
index 1c0e70b..0000000
--- a/media/codecs/xaac/C2SoftXaacDec.cpp
+++ /dev/null
@@ -1,1583 +0,0 @@
-/*
- * Copyright (C) 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 "C2SoftXaacDec"
-#include <log/log.h>
-
-#include <inttypes.h>
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Interface.h>
-
-#include "C2SoftXaacDec.h"
-
-#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
-#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
-#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
-// names of properties that can be used to override the default DRC settings
-#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
-#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
-#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
-#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
-#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
-#define PROP_DRC_OVERRIDE_EFFECT_TYPE "ro.aac_drc_effect_type"
-
-#define RETURN_IF_FATAL(retval, str) \
- if (retval & IA_FATAL_ERROR) { \
- ALOGE("Error in %s: Returned: %d", str, retval); \
- return retval; \
- } else if (retval != IA_NO_ERROR) { \
- ALOGW("Warning in %s: Returned: %d", str, retval); \
- }
-
-
-namespace android {
-
-constexpr char COMPONENT_NAME[] = "c2.android.xaac.decoder";
-
-class C2SoftXaacDec::IntfImpl : public C2InterfaceHelper {
-public:
- explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
- : C2InterfaceHelper(helper) {
-
- setDerivedInstance(this);
-
- addParameter(
- DefineParam(mInputFormat, C2_NAME_INPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::input(0u, C2FormatCompressed))
- .build());
-
- addParameter(
- DefineParam(mOutputFormat, C2_NAME_OUTPUT_STREAM_FORMAT_SETTING)
- .withConstValue(new C2StreamFormatConfig::output(0u, C2FormatAudio))
- .build());
-
- addParameter(
- DefineParam(mInputMediaType, C2_NAME_INPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::input>(
- MEDIA_MIMETYPE_AUDIO_AAC))
- .build());
-
- addParameter(
- DefineParam(mOutputMediaType, C2_NAME_OUTPUT_PORT_MIME_SETTING)
- .withConstValue(AllocSharedString<C2PortMimeConfig::output>(
- MEDIA_MIMETYPE_AUDIO_RAW))
- .build());
-
- addParameter(
- DefineParam(mSampleRate, C2_NAME_STREAM_SAMPLE_RATE_SETTING)
- .withDefault(new C2StreamSampleRateInfo::output(0u, 44100))
- .withFields({C2F(mSampleRate, value).oneOf({
- 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
- })})
- .withSetter((Setter<decltype(*mSampleRate)>::StrictValueWithNoDeps))
- .build());
-
- addParameter(
- DefineParam(mChannelCount, C2_NAME_STREAM_CHANNEL_COUNT_SETTING)
- .withDefault(new C2StreamChannelCountInfo::output(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 8)})
- .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mBitrate, C2_NAME_STREAM_BITRATE_SETTING)
- .withDefault(new C2BitrateTuning::input(0u, 64000))
- .withFields({C2F(mBitrate, value).inRange(8000, 960000)})
- .withSetter(Setter<decltype(*mBitrate)>::NonStrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mInputMaxBufSize, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE)
- .withConstValue(new C2StreamMaxBufferSizeInfo::input(0u, 8192))
- .build());
-
- addParameter(
- DefineParam(mAacFormat, C2_NAME_STREAM_AAC_FORMAT_SETTING)
- .withDefault(new C2StreamAacFormatInfo::input(0u, C2AacStreamFormatRaw))
- .withFields({C2F(mAacFormat, value).oneOf({
- C2AacStreamFormatRaw, C2AacStreamFormatAdts
- })})
- .withSetter(Setter<decltype(*mAacFormat)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL)
- .withDefault(new C2StreamProfileLevelInfo::input(0u,
- C2Config::PROFILE_AAC_LC, C2Config::LEVEL_UNUSED))
- .withFields({
- C2F(mProfileLevel, profile).oneOf({
- C2Config::PROFILE_AAC_LC,
- C2Config::PROFILE_AAC_HE,
- C2Config::PROFILE_AAC_HE_PS,
- C2Config::PROFILE_AAC_LD,
- C2Config::PROFILE_AAC_ELD,
- C2Config::PROFILE_AAC_XHE}),
- C2F(mProfileLevel, level).oneOf({
- C2Config::LEVEL_UNUSED
- })
- })
- .withSetter(ProfileLevelSetter)
- .build());
-
- addParameter(
- DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
- .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
- .withFields({
- C2F(mDrcCompressMode, value).oneOf({
- C2Config::DRC_COMPRESSION_ODM_DEFAULT,
- C2Config::DRC_COMPRESSION_NONE,
- C2Config::DRC_COMPRESSION_LIGHT,
- C2Config::DRC_COMPRESSION_HEAVY})
- })
- .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
- .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
- .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
- .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
- .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
- .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
- .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
- .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
- .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
- .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
- .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
- .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
- .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
- .build());
-
- addParameter(
- DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
- .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
- .withFields({
- C2F(mDrcEffectType, value).oneOf({
- C2Config::DRC_EFFECT_ODM_DEFAULT,
- C2Config::DRC_EFFECT_OFF,
- C2Config::DRC_EFFECT_NONE,
- C2Config::DRC_EFFECT_LATE_NIGHT,
- C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
- C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
- C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
- C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
- C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
- })
- .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
- .build());
- }
-
- bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
- uint32_t getBitrate() const { return mBitrate->value; }
- static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me) {
- (void)mayBlock;
- (void)me; // TODO: validate
- return C2R::Ok();
- }
- int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
- int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
- int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
- int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
- int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
- int32_t getDrcEffectType() const { return mDrcEffectType->value; }
-
-private:
- std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
- std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
- std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
- std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
- std::shared_ptr<C2StreamSampleRateInfo::output> mSampleRate;
- std::shared_ptr<C2StreamChannelCountInfo::output> mChannelCount;
- std::shared_ptr<C2BitrateTuning::input> mBitrate;
- std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
- std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
- std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
- std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
- std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
- std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
- std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
- std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
- std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
- // TODO Add : C2StreamAacSbrModeTuning
-};
-
-C2SoftXaacDec::C2SoftXaacDec(
- const char* name,
- c2_node_id_t id,
- const std::shared_ptr<IntfImpl> &intfImpl)
- : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
- mIntf(intfImpl),
- mXheaacCodecHandle(nullptr),
- mMpegDDrcHandle(nullptr),
- mOutputDrainBuffer(nullptr) {
-}
-
-C2SoftXaacDec::~C2SoftXaacDec() {
- onRelease();
-}
-
-c2_status_t C2SoftXaacDec::onInit() {
- mOutputFrameLength = 1024;
- mInputBuffer = nullptr;
- mOutputBuffer = nullptr;
- mSampFreq = 0;
- mNumChannels = 0;
- mPcmWdSz = 0;
- mChannelMask = 0;
- mNumOutBytes = 0;
- mCurFrameIndex = 0;
- mCurTimestamp = 0;
- mIsCodecInitialized = false;
- mIsCodecConfigFlushRequired = false;
- mSignalledOutputEos = false;
- mSignalledError = false;
- mOutputDrainBufferWritePos = 0;
- mDRCFlag = 0;
- mMpegDDRCPresent = 0;
- mMemoryVec.clear();
- mDrcMemoryVec.clear();
-
- IA_ERRORCODE err = initDecoder();
- return err == IA_NO_ERROR ? C2_OK : C2_CORRUPTED;
-
-}
-
-c2_status_t C2SoftXaacDec::onStop() {
- mOutputFrameLength = 1024;
- drainDecoder();
- // reset the "configured" state
- mSampFreq = 0;
- mNumChannels = 0;
- mPcmWdSz = 0;
- mChannelMask = 0;
- mNumOutBytes = 0;
- mCurFrameIndex = 0;
- mCurTimestamp = 0;
- mSignalledOutputEos = false;
- mSignalledError = false;
- mOutputDrainBufferWritePos = 0;
- mDRCFlag = 0;
- mMpegDDRCPresent = 0;
-
- return C2_OK;
-}
-
-void C2SoftXaacDec::onReset() {
- (void)onStop();
-}
-
-void C2SoftXaacDec::onRelease() {
- IA_ERRORCODE errCode = deInitXAACDecoder();
- if (IA_NO_ERROR != errCode) ALOGE("deInitXAACDecoder() failed %d", errCode);
-
- errCode = deInitMPEGDDDrc();
- if (IA_NO_ERROR != errCode) ALOGE("deInitMPEGDDDrc() failed %d", errCode);
-
- if (mOutputDrainBuffer) {
- delete[] mOutputDrainBuffer;
- mOutputDrainBuffer = nullptr;
- }
-}
-
-IA_ERRORCODE C2SoftXaacDec::initDecoder() {
- ALOGV("initDecoder()");
- IA_ERRORCODE err_code = IA_NO_ERROR;
-
- err_code = initXAACDecoder();
- if (err_code != IA_NO_ERROR) {
- ALOGE("initXAACDecoder Failed");
- /* Call deInit to free any allocated memory */
- deInitXAACDecoder();
- return IA_FATAL_ERROR;
- }
-
- if (!mOutputDrainBuffer) {
- mOutputDrainBuffer = new (std::nothrow) char[kOutputDrainBufferSize];
- if (!mOutputDrainBuffer) return IA_FATAL_ERROR;
- }
-
- err_code = initXAACDrc();
- RETURN_IF_FATAL(err_code, "initXAACDrc");
-
-
- return IA_NO_ERROR;
-}
-
-static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
-}
-
-void C2SoftXaacDec::finishWork(const std::unique_ptr<C2Work>& work,
- const std::shared_ptr<C2BlockPool>& pool) {
- ALOGV("mCurFrameIndex = %" PRIu64, mCurFrameIndex);
-
- std::shared_ptr<C2LinearBlock> block;
- C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
- // TODO: error handling, proper usage, etc.
- c2_status_t err =
- pool->fetchLinearBlock(mOutputDrainBufferWritePos, usage, &block);
- if (err != C2_OK) {
- ALOGE("fetchLinearBlock failed : err = %d", err);
- work->result = C2_NO_MEMORY;
- return;
- }
- C2WriteView wView = block->map().get();
- int16_t* outBuffer = reinterpret_cast<int16_t*>(wView.data());
- memcpy(outBuffer, mOutputDrainBuffer, mOutputDrainBufferWritePos);
- mOutputDrainBufferWritePos = 0;
-
- auto fillWork = [buffer = createLinearBuffer(block)](
- const std::unique_ptr<C2Work>& work) {
- uint32_t flags = 0;
- if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- ALOGV("signalling eos");
- }
- work->worklets.front()->output.flags = (C2FrameData::flags_t)flags;
- work->worklets.front()->output.buffers.clear();
- work->worklets.front()->output.buffers.push_back(buffer);
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->workletsProcessed = 1u;
- };
- if (work && work->input.ordinal.frameIndex == c2_cntr64_t(mCurFrameIndex)) {
- fillWork(work);
- } else {
- finish(mCurFrameIndex, fillWork);
- }
-
- ALOGV("out timestamp %" PRIu64 " / %u", mCurTimestamp, block->capacity());
-}
-
-void C2SoftXaacDec::process(const std::unique_ptr<C2Work>& work,
- const std::shared_ptr<C2BlockPool>& pool) {
- // Initialize output work
- work->result = C2_OK;
- work->workletsProcessed = 1u;
- work->worklets.front()->output.configUpdate.clear();
- work->worklets.front()->output.flags = work->input.flags;
-
- if (mSignalledError || mSignalledOutputEos) {
- work->result = C2_BAD_VALUE;
- return;
- }
- uint8_t* inBuffer = nullptr;
- uint32_t inBufferLength = 0;
- C2ReadView view = mDummyReadView;
- size_t offset = 0u;
- size_t size = 0u;
- if (!work->input.buffers.empty()) {
- view = work->input.buffers[0]->data().linearBlocks().front().map().get();
- size = view.capacity();
- }
- if (size && view.error()) {
- ALOGE("read view map failed %d", view.error());
- work->result = view.error();
- return;
- }
-
- bool eos = (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
- bool codecConfig =
- (work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0;
- if (codecConfig) {
- if (size == 0u) {
- ALOGE("empty codec config");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- // const_cast because of libAACdec method signature.
- inBuffer = const_cast<uint8_t*>(view.data() + offset);
- inBufferLength = size;
-
- /* GA header configuration sent to Decoder! */
- IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
- if (IA_NO_ERROR != err_code) {
- ALOGE("configXAACDecoder err_code = %d", err_code);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- work->worklets.front()->output.flags = work->input.flags;
- work->worklets.front()->output.ordinal = work->input.ordinal;
- work->worklets.front()->output.buffers.clear();
- return;
- }
-
- mCurFrameIndex = work->input.ordinal.frameIndex.peeku();
- mCurTimestamp = work->input.ordinal.timestamp.peeku();
- mOutputDrainBufferWritePos = 0;
- char* tempOutputDrainBuffer = mOutputDrainBuffer;
- while (size > 0u) {
- if ((kOutputDrainBufferSize * sizeof(int16_t) -
- mOutputDrainBufferWritePos) <
- (mOutputFrameLength * sizeof(int16_t) * mNumChannels)) {
- ALOGV("skipping decode: not enough space left in DrainBuffer");
- break;
- }
-
- ALOGV("inAttribute size = %zu", size);
- if (mIntf->isAdts()) {
- ALOGV("ADTS");
- size_t adtsHeaderSize = 0;
- // skip 30 bits, aac_frame_length follows.
- // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
-
- const uint8_t* adtsHeader = view.data() + offset;
- bool signalError = false;
- if (size < 7) {
- ALOGE("Audio data too short to contain even the ADTS header. "
- "Got %zu bytes.", size);
- hexdump(adtsHeader, size);
- signalError = true;
- } else {
- bool protectionAbsent = (adtsHeader[1] & 1);
- unsigned aac_frame_length = ((adtsHeader[3] & 3) << 11) |
- (adtsHeader[4] << 3) |
- (adtsHeader[5] >> 5);
-
- if (size < aac_frame_length) {
- ALOGE("Not enough audio data for the complete frame. "
- "Got %zu bytes, frame size according to the ADTS "
- "header is %u bytes.", size, aac_frame_length);
- hexdump(adtsHeader, size);
- signalError = true;
- } else {
- adtsHeaderSize = (protectionAbsent ? 7 : 9);
- if (aac_frame_length < adtsHeaderSize) {
- signalError = true;
- } else {
- // const_cast because of libAACdec method signature.
- inBuffer =
- const_cast<uint8_t*>(adtsHeader + adtsHeaderSize);
- inBufferLength = aac_frame_length - adtsHeaderSize;
-
- offset += adtsHeaderSize;
- size -= adtsHeaderSize;
- }
- }
- }
-
- if (signalError) {
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- } else {
- ALOGV("Non ADTS");
- // const_cast because of libAACdec method signature.
- inBuffer = const_cast<uint8_t*>(view.data() + offset);
- inBufferLength = size;
- }
-
- signed int prevSampleRate = mSampFreq;
- signed int prevNumChannels = mNumChannels;
-
- /* XAAC decoder expects first frame to be fed via configXAACDecoder API
- * which should initialize the codec. Once this state is reached, call the
- * decodeXAACStream API with same frame to decode! */
- if (!mIsCodecInitialized) {
- IA_ERRORCODE err_code = configXAACDecoder(inBuffer, inBufferLength);
- if (IA_NO_ERROR != err_code) {
- ALOGE("configXAACDecoder Failed 2 err_code = %d", err_code);
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- if ((mSampFreq != prevSampleRate) ||
- (mNumChannels != prevNumChannels)) {
- ALOGI("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
- prevSampleRate, mSampFreq, prevNumChannels, mNumChannels);
-
- C2StreamSampleRateInfo::output sampleRateInfo(0u, mSampFreq);
- C2StreamChannelCountInfo::output channelCountInfo(0u, mNumChannels);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mIntf->config(
- { &sampleRateInfo, &channelCountInfo },
- C2_MAY_BLOCK,
- &failures);
- if (err == OK) {
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(sampleRateInfo));
- work->worklets.front()->output.configUpdate.push_back(
- C2Param::Copy(channelCountInfo));
- } else {
- ALOGE("Config Update failed");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- }
- }
-
- signed int bytesConsumed = 0;
- IA_ERRORCODE errorCode = IA_NO_ERROR;
- if (mIsCodecInitialized) {
- mIsCodecConfigFlushRequired = true;
- errorCode = decodeXAACStream(inBuffer, inBufferLength,
- &bytesConsumed, &mNumOutBytes);
- } else if (!mIsCodecConfigFlushRequired) {
- ALOGW("Assumption that first frame after header initializes decoder Failed!");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
- size -= bytesConsumed;
- offset += bytesConsumed;
-
- if (inBufferLength != (uint32_t)bytesConsumed)
- ALOGW("All data not consumed");
-
- /* In case of error, decoder would have given out empty buffer */
- if ((IA_NO_ERROR != errorCode) && (0 == mNumOutBytes) && mIsCodecInitialized)
- mNumOutBytes = mOutputFrameLength * (mPcmWdSz / 8) * mNumChannels;
-
- if (!bytesConsumed) {
- ALOGW("bytesConsumed = 0 should never happen");
- }
-
- if ((uint32_t)mNumOutBytes >
- mOutputFrameLength * sizeof(int16_t) * mNumChannels) {
- ALOGE("mNumOutBytes > mOutputFrameLength * sizeof(int16_t) * mNumChannels, should never happen");
- mSignalledError = true;
- work->result = C2_CORRUPTED;
- return;
- }
-
- if (IA_NO_ERROR != errorCode) {
- // TODO: check for overflow, ASAN
- memset(mOutputBuffer, 0, mNumOutBytes);
-
- // Discard input buffer.
- size = 0;
-
- // fall through
- }
- memcpy(tempOutputDrainBuffer, mOutputBuffer, mNumOutBytes);
- tempOutputDrainBuffer += mNumOutBytes;
- mOutputDrainBufferWritePos += mNumOutBytes;
- }
-
- if (mOutputDrainBufferWritePos) {
- finishWork(work, pool);
- } else {
- fillEmptyWork(work);
- }
- if (eos) mSignalledOutputEos = true;
-}
-
-c2_status_t C2SoftXaacDec::drain(uint32_t drainMode,
- const std::shared_ptr<C2BlockPool>& pool) {
- (void)pool;
- if (drainMode == NO_DRAIN) {
- ALOGW("drain with NO_DRAIN: no-op");
- return C2_OK;
- }
- if (drainMode == DRAIN_CHAIN) {
- ALOGW("DRAIN_CHAIN not supported");
- return C2_OMITTED;
- }
-
- return C2_OK;
-}
-
-IA_ERRORCODE C2SoftXaacDec::configflushDecode() {
- IA_ERRORCODE err_code;
- uint32_t ui_init_done;
- uint32_t inBufferLength = 8203;
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_FLUSH_MEM,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_INPUT_BYTES,
- 0,
- &inBufferLength);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_FLUSH_MEM,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_FLUSH_MEM");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_DONE_QUERY,
- &ui_init_done);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY");
-
- if (ui_init_done) {
- err_code = getXAACStreamInfo();
- RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
- ALOGV("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
- mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
- mIsCodecInitialized = true;
- }
- return IA_NO_ERROR;
-}
-
-c2_status_t C2SoftXaacDec::onFlush_sm() {
- if (mIsCodecInitialized) {
- IA_ERRORCODE err_code = configflushDecode();
- if (err_code != IA_NO_ERROR) {
- ALOGE("Error in configflushDecode: Error %d", err_code);
- }
- }
- drainDecoder();
- mSignalledOutputEos = false;
- mSignalledError = false;
-
- return C2_OK;
-}
-
-IA_ERRORCODE C2SoftXaacDec::drainDecoder() {
- /* Output delay compensation logic should sit here. */
- /* Nothing to be done as XAAC decoder does not introduce output buffer delay */
-
- return 0;
-}
-
-IA_ERRORCODE C2SoftXaacDec::initXAACDecoder() {
- /* First part */
- /* Error Handler Init */
- /* Get Library Name, Library Version and API Version */
- /* Initialize API structure + Default config set */
- /* Set config params from user */
- /* Initialize memory tables */
- /* Get memory information and allocate memory */
-
- mInputBufferSize = 0;
- mInputBuffer = nullptr;
- mOutputBuffer = nullptr;
- /* Process struct initing end */
-
- /* ******************************************************************/
- /* Initialize API structure and set config params to default */
- /* ******************************************************************/
- /* API size */
- uint32_t pui_api_size;
- /* Get the API size */
- IA_ERRORCODE err_code = ixheaacd_dec_api(nullptr,
- IA_API_CMD_GET_API_SIZE,
- 0,
- &pui_api_size);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
-
- /* Allocate memory for API */
- mXheaacCodecHandle = memalign(4, pui_api_size);
- if (!mXheaacCodecHandle) {
- ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
- return IA_FATAL_ERROR;
- }
- mMemoryVec.push(mXheaacCodecHandle);
-
- /* Set the config params to default values */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
-
- /* Get the API size */
- err_code = ia_drc_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
-
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_API_SIZE");
-
- /* Allocate memory for API */
- mMpegDDrcHandle = memalign(4, pui_api_size);
- if (!mMpegDDrcHandle) {
- ALOGE("malloc for pui_api_size + 4 >> %d Failed", pui_api_size + 4);
- return IA_FATAL_ERROR;
- }
- mMemoryVec.push(mMpegDDrcHandle);
-
- /* Set the config params to default values */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
-
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS");
-
- /* ******************************************************************/
- /* Set config parameters */
- /* ******************************************************************/
- uint32_t ui_mp4_flag = 1;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4,
- &ui_mp4_flag);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4");
-
- /* ******************************************************************/
- /* Initialize Memory info tables */
- /* ******************************************************************/
- uint32_t ui_proc_mem_tabs_size;
- pVOID pv_alloc_ptr;
- /* Get memory info tables size */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_MEMTABS_SIZE,
- 0,
- &ui_proc_mem_tabs_size);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEMTABS_SIZE");
-
- pv_alloc_ptr = memalign(4, ui_proc_mem_tabs_size);
- if (!pv_alloc_ptr) {
- ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!", ui_proc_mem_tabs_size + 4);
- return IA_FATAL_ERROR;
- }
- mMemoryVec.push(pv_alloc_ptr);
-
- /* Set pointer for process memory tables */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_MEMTABS_PTR,
- 0,
- pv_alloc_ptr);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEMTABS_PTR");
-
- /* initialize the API, post config, fill memory tables */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
-
- /* ******************************************************************/
- /* Allocate Memory with info from library */
- /* ******************************************************************/
- /* There are four different types of memories, that needs to be allocated */
- /* persistent,scratch,input and output */
- for (int i = 0; i < 4; i++) {
- int ui_size = 0, ui_alignment = 0, ui_type = 0;
-
- /* Get memory size */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_MEM_INFO_SIZE,
- i,
- &ui_size);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
-
- /* Get memory alignment */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_MEM_INFO_ALIGNMENT,
- i,
- &ui_alignment);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
-
- /* Get memory type */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_MEM_INFO_TYPE,
- i,
- &ui_type);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
-
- pv_alloc_ptr = memalign(ui_alignment, ui_size);
- if (!pv_alloc_ptr) {
- ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!",
- ui_size + ui_alignment);
- return IA_FATAL_ERROR;
- }
- mMemoryVec.push(pv_alloc_ptr);
-
- /* Set the buffer pointer */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_MEM_PTR,
- i,
- pv_alloc_ptr);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
- if (ui_type == IA_MEMTYPE_INPUT) {
- mInputBuffer = (pWORD8)pv_alloc_ptr;
- mInputBufferSize = ui_size;
- }
- if (ui_type == IA_MEMTYPE_OUTPUT)
- mOutputBuffer = (pWORD8)pv_alloc_ptr;
- }
- /* End first part */
-
- return IA_NO_ERROR;
-}
-
-status_t C2SoftXaacDec::initXAACDrc() {
- IA_ERRORCODE err_code = IA_NO_ERROR;
- unsigned int ui_drc_val;
- // DRC_PRES_MODE_WRAP_DESIRED_TARGET
- int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
- ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
- ui_drc_val = (unsigned int)targetRefLevel;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
- &ui_drc_val);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
-
- /* Use ui_drc_val from PROP_DRC_OVERRIDE_REF_LEVEL or DRC_DEFAULT_MOBILE_REF_LEVEL
- * for IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS too */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
-
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
-
- int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
- ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
- ui_drc_val = (unsigned int)attenuationFactor;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT,
- &ui_drc_val);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
-
- // DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
- int32_t boostFactor = mIntf->getDrcBoostFactor();
- ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
- ui_drc_val = (unsigned int)boostFactor;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST,
- &ui_drc_val);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
-
- // DRC_PRES_MODE_WRAP_DESIRED_HEAVY
- int32_t compressMode = mIntf->getDrcCompressMode();
- ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
- ui_drc_val = (unsigned int)compressMode;
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
- &ui_drc_val);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
-
- // AAC_UNIDRC_SET_EFFECT
- int32_t effectType = mIntf->getDrcEffectType();
- ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
- ui_drc_val = (unsigned int)effectType;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
-
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
-
- return IA_NO_ERROR;
-}
-
-IA_ERRORCODE C2SoftXaacDec::deInitXAACDecoder() {
- ALOGV("deInitXAACDecoder");
-
- /* Error code */
- IA_ERRORCODE err_code = IA_NO_ERROR;
-
- if (mXheaacCodecHandle) {
- /* Tell that the input is over in this buffer */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INPUT_OVER,
- 0,
- nullptr);
- }
-
- /* Irrespective of error returned in IA_API_CMD_INPUT_OVER, free allocated memory */
- for (void* buf : mMemoryVec) {
- if (buf) free(buf);
- }
- mMemoryVec.clear();
- mXheaacCodecHandle = nullptr;
-
- return err_code;
-}
-
-IA_ERRORCODE C2SoftXaacDec::deInitMPEGDDDrc() {
- ALOGV("deInitMPEGDDDrc");
-
- for (void* buf : mDrcMemoryVec) {
- if (buf) free(buf);
- }
- mDrcMemoryVec.clear();
- return IA_NO_ERROR;
-}
-
-IA_ERRORCODE C2SoftXaacDec::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
- if (mInputBufferSize < inBufferLength) {
- ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
- return false;
- }
- /* Copy the buffer passed by Android plugin to codec input buffer */
- memcpy(mInputBuffer, inBuffer, inBufferLength);
-
- /* Set number of bytes to be processed */
- IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_INPUT_BYTES,
- 0,
- &inBufferLength);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
-
- if (mIsCodecConfigFlushRequired) {
- /* If codec is already initialized, then GA header is passed again */
- /* Need to call the Flush API instead of INIT_PROCESS */
- mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_GA_HDR,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_GA_HDR");
- } else {
- /* Initialize the process */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_PROCESS,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
- }
-
- uint32_t ui_init_done;
- /* Checking for end of initialization */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_DONE_QUERY,
- &ui_init_done);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_DONE_QUERY");
-
- /* How much buffer is used in input buffers */
- int32_t i_bytes_consumed;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CURIDX_INPUT_BUF,
- 0,
- &i_bytes_consumed);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
-
- if (ui_init_done) {
- err_code = getXAACStreamInfo();
- RETURN_IF_FATAL(err_code, "getXAACStreamInfo");
- ALOGI("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
- mSampFreq, mNumChannels, mPcmWdSz, mChannelMask, mOutputFrameLength);
- mIsCodecInitialized = true;
-
- err_code = configMPEGDDrc();
- RETURN_IF_FATAL(err_code, "configMPEGDDrc");
- }
-
- return IA_NO_ERROR;
-}
-IA_ERRORCODE C2SoftXaacDec::initMPEGDDDrc() {
- IA_ERRORCODE err_code = IA_NO_ERROR;
-
- for (int i = 0; i < (WORD32)2; i++) {
- WORD32 ui_size, ui_alignment, ui_type;
- pVOID pv_alloc_ptr;
-
- /* Get memory size */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
-
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_SIZE");
-
- /* Get memory alignment */
- err_code =
- ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
-
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_ALIGNMENT");
-
- /* Get memory type */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_MEM_INFO_TYPE");
-
- pv_alloc_ptr = memalign(4, ui_size);
- if (pv_alloc_ptr == nullptr) {
- ALOGE(" Cannot create requested memory %d", ui_size);
- return IA_FATAL_ERROR;
- }
- mDrcMemoryVec.push(pv_alloc_ptr);
-
- /* Set the buffer pointer */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i, pv_alloc_ptr);
-
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
- }
-
- WORD32 ui_size;
- ui_size = 8192 * 2;
-
- mDrcInBuf = (int8_t*)memalign(4, ui_size);
- if (mDrcInBuf == nullptr) {
- ALOGE(" Cannot create requested memory %d", ui_size);
- return IA_FATAL_ERROR;
- }
- mDrcMemoryVec.push(mDrcInBuf);
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
-
- mDrcOutBuf = (int8_t*)memalign(4, ui_size);
- if (mDrcOutBuf == nullptr) {
- ALOGE(" Cannot create requested memory %d", ui_size);
- return IA_FATAL_ERROR;
- }
- mDrcMemoryVec.push(mDrcOutBuf);
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_MEM_PTR");
-
- return IA_NO_ERROR;
-}
-int C2SoftXaacDec::configMPEGDDrc() {
- IA_ERRORCODE err_code = IA_NO_ERROR;
- int i_effect_type;
- int i_loud_norm;
- int i_target_loudness;
- unsigned int i_sbr_mode;
-
- /* Sampling Frequency */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ");
- /* Total Number of Channels */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
-
- /* PCM word size */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ");
-
- /*Set Effect Type*/
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE, &i_effect_type);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
-
- /*Set target loudness */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS,
- &i_target_loudness);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
-
- /*Set loud_norm_flag*/
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM, &i_loud_norm);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
-
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS");
-
- /* Free any memory that is allocated for MPEG D Drc so far */
- deInitMPEGDDDrc();
-
- err_code = initMPEGDDDrc();
- if (err_code != IA_NO_ERROR) {
- ALOGE("initMPEGDDDrc failed with error %d", err_code);
- deInitMPEGDDDrc();
- return err_code;
- }
-
- /* DRC buffers
- buf[0] - contains extension element pay load loudness related
- buf[1] - contains extension element pay load*/
- {
- VOID* p_array[2][16];
- WORD32 ii;
- WORD32 buf_sizes[2][16];
- WORD32 num_elements;
- WORD32 num_config_ext;
- WORD32 bit_str_fmt = 1;
-
- WORD32 uo_num_chan;
-
- memset(buf_sizes, 0, 32 * sizeof(WORD32));
-
- err_code =
- ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES, &buf_sizes[0][0]);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR");
-
- err_code =
- ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_SET_BUFF_PTR");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT, &num_config_ext);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT");
-
- for (ii = 0; ii < num_config_ext; ii++) {
- /*copy loudness bitstream*/
- if (buf_sizes[0][ii] > 0) {
- memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
-
- /*Set bitstream_split_format */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
-
- /* Set number of bytes to be processed */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
- &buf_sizes[0][ii]);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IL_BS");
-
- /* Execute process */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF");
-
- mDRCFlag = 1;
- }
- }
-
- for (ii = 0; ii < num_elements; ii++) {
- /*copy config bitstream*/
- if (buf_sizes[1][ii] > 0) {
- memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
- /* Set number of bytes to be processed */
-
- /*Set bitstream_split_format */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
- &buf_sizes[1][ii]);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES_IC_BS");
-
- /* Execute process */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr);
-
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF");
-
- mDRCFlag = 1;
- }
- }
-
- if (mDRCFlag == 1) {
- mMpegDDRCPresent = 1;
- } else {
- mMpegDDRCPresent = 0;
- }
-
- /*Read interface buffer config file bitstream*/
- if (mMpegDDRCPresent == 1) {
- WORD32 interface_is_present = 1;
-
- if (i_sbr_mode != 0) {
- if (i_sbr_mode == 1) {
- mOutputFrameLength = 2048;
- } else if (i_sbr_mode == 3) {
- mOutputFrameLength = 4096;
- } else {
- mOutputFrameLength = 1024;
- }
- } else {
- mOutputFrameLength = 4096;
- }
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE, (WORD32 *)&mOutputFrameLength);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE");
-
- err_code =
- ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT, &interface_is_present);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT");
-
- /* Execute process */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_PROCESS, nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_INIT_PROCESS");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS");
- }
- }
-
- return err_code;
-}
-
-IA_ERRORCODE C2SoftXaacDec::decodeXAACStream(uint8_t* inBuffer,
- uint32_t inBufferLength,
- int32_t* bytesConsumed,
- int32_t* outBytes) {
- if (mInputBufferSize < inBufferLength) {
- ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d", mInputBufferSize, inBufferLength);
- return -1;
- }
- /* Copy the buffer passed by Android plugin to codec input buffer */
- memcpy(mInputBuffer, inBuffer, inBufferLength);
-
- /* Set number of bytes to be processed */
- IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_SET_INPUT_BYTES,
- 0,
- &inBufferLength);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
-
- /* Execute process */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_EXECUTE,
- IA_CMD_TYPE_DO_EXECUTE,
- nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
-
- /* Checking for end of processing */
- uint32_t ui_exec_done;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_EXECUTE,
- IA_CMD_TYPE_DONE_QUERY,
- &ui_exec_done);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DONE_QUERY");
-
- if (ui_exec_done != 1) {
- VOID* p_array; // ITTIAM:buffer to handle gain payload
- WORD32 buf_size = 0; // ITTIAM:gain payload length
- WORD32 bit_str_fmt = 1;
- WORD32 gain_stream_flag = 1;
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN");
-
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF");
-
- if (buf_size > 0) {
- /*Set bitstream_split_format */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
-
- memcpy(mDrcInBuf, p_array, buf_size);
- /* Set number of bytes to be processed */
- err_code =
- ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS, 0, &buf_size);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
-
- /* Execute process */
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
- IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT");
-
- mMpegDDRCPresent = 1;
- }
- }
-
- /* How much buffer is used in input buffers */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CURIDX_INPUT_BUF,
- 0,
- bytesConsumed);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_CURIDX_INPUT_BUF");
-
- /* Get the output bytes */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_OUTPUT_BYTES,
- 0,
- outBytes);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_GET_OUTPUT_BYTES");
-
- if (mMpegDDRCPresent == 1) {
- memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0, outBytes);
- RETURN_IF_FATAL(err_code, "IA_API_CMD_SET_INPUT_BYTES");
-
- err_code =
- ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, nullptr);
- RETURN_IF_FATAL(err_code, "IA_CMD_TYPE_DO_EXECUTE");
-
- memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
- }
- return IA_NO_ERROR;
-}
-
-IA_ERRORCODE C2SoftXaacDec::getXAACStreamInfo() {
- IA_ERRORCODE err_code = IA_NO_ERROR;
-
- /* Sampling frequency */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ,
- &mSampFreq);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ");
-
- /* Total Number of Channels */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
- &mNumChannels);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS");
- if (mNumChannels > MAX_CHANNEL_COUNT) {
- ALOGE(" No of channels are more than max channels\n");
- return IA_FATAL_ERROR;
- }
-
- /* PCM word size */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ,
- &mPcmWdSz);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ");
- if ((mPcmWdSz / 8) != 2) {
- ALOGE(" No of channels are more than max channels\n");
- return IA_FATAL_ERROR;
- }
-
- /* channel mask to tell the arrangement of channels in bit stream */
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
- &mChannelMask);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK");
-
- /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
- uint32_t ui_channel_mode;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
- &ui_channel_mode);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE");
- if (ui_channel_mode == 0)
- ALOGV("Channel Mode: MONO_OR_PS\n");
- else if (ui_channel_mode == 1)
- ALOGV("Channel Mode: STEREO\n");
- else if (ui_channel_mode == 2)
- ALOGV("Channel Mode: DUAL-MONO\n");
- else
- ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
-
- /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
- uint32_t ui_sbr_mode;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle,
- IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE,
- &ui_sbr_mode);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE");
- if (ui_sbr_mode == 0)
- ALOGV("SBR Mode: NOT_PRESENT\n");
- else if (ui_sbr_mode == 1)
- ALOGV("SBR Mode: PRESENT\n");
- else
- ALOGV("SBR Mode: ILLEGAL\n");
-
- /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
- /* For USAC it could be 1024 * 3 , support to query */
- /* not yet added in codec */
- mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
- ALOGI("mOutputFrameLength %d ui_sbr_mode %d", mOutputFrameLength, ui_sbr_mode);
-
- return IA_NO_ERROR;
-}
-
-IA_ERRORCODE C2SoftXaacDec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
- int32_t drcRefLevel,
- int32_t drcHeavyCompression,
- int32_t drEffectType) {
- IA_ERRORCODE err_code = IA_NO_ERROR;
-
- int32_t ui_drc_enable = 1;
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
- &ui_drc_enable);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE");
- if (drcCut != -1) {
- err_code =
- ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT");
- }
-
- if (drcBoost != -1) {
- err_code = ixheaacd_dec_api(
- mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST");
- }
-
- if (drcRefLevel != -1) {
- err_code = ixheaacd_dec_api(
- mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL, &drcRefLevel);
- RETURN_IF_FATAL(err_code,
- "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL");
- }
-
- if (drcRefLevel != -1) {
- err_code = ixheaacd_dec_api(
- mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS");
- }
-
- if (drcHeavyCompression != -1) {
- err_code =
- ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
- &drcHeavyCompression);
- RETURN_IF_FATAL(err_code,
- "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP");
- }
-
- err_code =
- ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE");
-
- int32_t i_effect_type, i_target_loudness, i_loud_norm;
- /*Set Effect Type*/
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
- &i_effect_type);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE");
-
- err_code =
- ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
-
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE");
-
- /*Set target loudness */
- err_code = ixheaacd_dec_api(
- mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
- RETURN_IF_FATAL(err_code,
- "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS,
- &i_target_loudness);
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS");
-
- /*Set loud_norm_flag*/
- err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
- IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
- &i_loud_norm);
- RETURN_IF_FATAL(err_code, "IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM");
-
- err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
- IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
-
- RETURN_IF_FATAL(err_code, "IA_DRC_DEC_CONFIG_DRC_LOUD_NORM");
-
- return IA_NO_ERROR;
-}
-
-class C2SoftXaacDecFactory : public C2ComponentFactory {
-public:
- C2SoftXaacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
- GetCodec2PlatformComponentStore()->getParamReflector())) {
- }
-
- virtual c2_status_t createComponent(
- c2_node_id_t id,
- std::shared_ptr<C2Component>* const component,
- std::function<void(C2Component*)> deleter) override {
- *component = std::shared_ptr<C2Component>(
- new C2SoftXaacDec(COMPONENT_NAME,
- id,
- std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual c2_status_t createInterface(
- c2_node_id_t id,
- std::shared_ptr<C2ComponentInterface>* const interface,
- std::function<void(C2ComponentInterface*)> deleter) override {
- *interface = std::shared_ptr<C2ComponentInterface>(
- new SimpleInterface<C2SoftXaacDec::IntfImpl>(
- COMPONENT_NAME, id, std::make_shared<C2SoftXaacDec::IntfImpl>(mHelper)),
- deleter);
- return C2_OK;
- }
-
- virtual ~C2SoftXaacDecFactory() override = default;
-
-private:
- std::shared_ptr<C2ReflectorHelper> mHelper;
-};
-
-} // namespace android
-
-extern "C" ::C2ComponentFactory* CreateCodec2Factory() {
- ALOGV("in %s", __func__);
- return new ::android::C2SoftXaacDecFactory();
-}
-
-extern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) {
- ALOGV("in %s", __func__);
- delete factory;
-}
diff --git a/media/codecs/xaac/C2SoftXaacDec.h b/media/codecs/xaac/C2SoftXaacDec.h
deleted file mode 100644
index 5c8567f..0000000
--- a/media/codecs/xaac/C2SoftXaacDec.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_C2_SOFT_XAAC_DEC_H_
-#define ANDROID_C2_SOFT_XAAC_DEC_H_
-#include <utils/Vector.h>
-#include <SimpleC2Component.h>
-
-#include "ixheaacd_type_def.h"
-#include "ixheaacd_error_standards.h"
-#include "ixheaacd_error_handler.h"
-#include "ixheaacd_apicmd_standards.h"
-#include "ixheaacd_memory_standards.h"
-#include "ixheaacd_aac_config.h"
-
-#include "impd_apicmd_standards.h"
-#include "impd_drc_config_params.h"
-
-#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
-#define MAX_NUM_BLOCKS 8 /* maximum number of audio blocks that can be decoded */
-
-extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj,
- WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
-extern "C" IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_module_obj,
- WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
-extern "C" IA_ERRORCODE ixheaacd_get_config_param(pVOID p_ia_process_api_obj,
- pWORD32 pi_samp_freq,
- pWORD32 pi_num_chan,
- pWORD32 pi_pcm_wd_sz,
- pWORD32 pi_channel_mask);
-
-namespace android {
-
-struct C2SoftXaacDec : public SimpleC2Component {
- class IntfImpl;
-
- C2SoftXaacDec(const char* name, c2_node_id_t id,
- const std::shared_ptr<IntfImpl>& intfImpl);
- virtual ~C2SoftXaacDec();
-
- // From SimpleC2Component
- c2_status_t onInit() override;
- c2_status_t onStop() override;
- void onReset() override;
- void onRelease() override;
- c2_status_t onFlush_sm() override;
- void process(
- const std::unique_ptr<C2Work> &work,
- const std::shared_ptr<C2BlockPool> &pool) override;
- c2_status_t drain(
- uint32_t drainMode,
- const std::shared_ptr<C2BlockPool> &pool) override;
-
-private:
- enum {
- kOutputDrainBufferSize = 2048 * MAX_CHANNEL_COUNT * MAX_NUM_BLOCKS,
- };
-
- std::shared_ptr<IntfImpl> mIntf;
- void* mXheaacCodecHandle;
- void* mMpegDDrcHandle;
- uint32_t mInputBufferSize;
- uint32_t mOutputFrameLength;
- int8_t* mInputBuffer;
- int8_t* mOutputBuffer;
- int32_t mSampFreq;
- int32_t mNumChannels;
- int32_t mPcmWdSz;
- int32_t mChannelMask;
- int32_t mNumOutBytes;
- uint64_t mCurFrameIndex;
- uint64_t mCurTimestamp;
- bool mIsCodecInitialized;
- bool mIsCodecConfigFlushRequired;
- int8_t* mDrcInBuf;
- int8_t* mDrcOutBuf;
- int32_t mMpegDDRCPresent;
- int32_t mDRCFlag;
-
- Vector<void*> mMemoryVec;
- Vector<void*> mDrcMemoryVec;
-
- size_t mInputBufferCount __unused;
- size_t mOutputBufferCount __unused;
- bool mSignalledOutputEos;
- bool mSignalledError;
- char* mOutputDrainBuffer;
- uint32_t mOutputDrainBufferWritePos;
-
- IA_ERRORCODE initDecoder();
- IA_ERRORCODE setDrcParameter();
- IA_ERRORCODE configflushDecode();
- IA_ERRORCODE drainDecoder();
- void finishWork(const std::unique_ptr<C2Work>& work,
- const std::shared_ptr<C2BlockPool>& pool);
-
- IA_ERRORCODE initXAACDrc();
- IA_ERRORCODE initXAACDecoder();
- IA_ERRORCODE deInitXAACDecoder();
- IA_ERRORCODE initMPEGDDDrc();
- IA_ERRORCODE deInitMPEGDDDrc();
- IA_ERRORCODE configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
- int configMPEGDDrc();
- IA_ERRORCODE decodeXAACStream(uint8_t* inBuffer,
- uint32_t inBufferLength,
- int32_t* bytesConsumed,
- int32_t* outBytes);
- IA_ERRORCODE getXAACStreamInfo();
- IA_ERRORCODE setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
- int32_t drcRefLevel, int32_t drcHeavyCompression,
- int32_t drEffectType);
-
- C2_DO_NOT_COPY(C2SoftXaacDec);
-};
-
-} // namespace android
-
-#endif // C2_SOFT_XAAC_H_
diff --git a/media/sfplugin/Android.bp b/media/sfplugin/Android.bp
deleted file mode 100644
index 95d2740..0000000
--- a/media/sfplugin/Android.bp
+++ /dev/null
@@ -1,60 +0,0 @@
-cc_library_shared {
- name: "libstagefright_ccodec",
-
- srcs: [
- "C2OMXNode.cpp",
- "CCodec.cpp",
- "CCodecBufferChannel.cpp",
- "CCodecConfig.cpp",
- "Codec2Buffer.cpp",
- "Codec2InfoBuilder.cpp",
- "ReflectedParamUpdater.cpp",
- "SkipCutBuffer.cpp",
- ],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-
- header_libs: [
- "libmediadrm_headers",
- "libstagefright_codec2_internal",
- "media_ndk_headers",
- ],
-
- shared_libs: [
- "android.hardware.cas.native@1.0",
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hardware.media.omx@1.0",
- "hardware.google.media.c2@1.0",
- "libbase",
- "libbinder",
- "libcodec2_hidl_client",
- "libcutils",
- "libgui",
- "libhidlallocatorutils",
- "libhidlbase",
- "liblog",
- "libmedia_codeclist",
- "libmedia_omx",
- "libstagefright_bufferqueue_helper",
- "libstagefright_ccodec_utils",
- "libstagefright_codec2",
- "libstagefright_codec2_vndk",
- "libstagefright_codecbase",
- "libstagefright_foundation",
- "libstagefright_omx_utils",
- "libstagefright_xmlparser",
- "libui",
- "libutils",
- ],
-
- sanitize: {
- cfi: true,
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- },
-}
diff --git a/media/sfplugin/C2OMXNode.cpp b/media/sfplugin/C2OMXNode.cpp
deleted file mode 100644
index 03d859a..0000000
--- a/media/sfplugin/C2OMXNode.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * 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.
- */
-
-#ifdef __LP64__
-#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
-#endif
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "C2OMXNode"
-#include <log/log.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2BlockInternal.h>
-#include <C2Component.h>
-#include <C2PlatformSupport.h>
-
-#include <OMX_Component.h>
-#include <OMX_Index.h>
-#include <OMX_IndexExt.h>
-
-#include <media/stagefright/omx/OMXUtils.h>
-#include <media/stagefright/MediaErrors.h>
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-#include "C2OMXNode.h"
-
-namespace android {
-
-namespace {
-
-class Buffer2D : public C2Buffer {
-public:
- explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
-};
-
-} // namespace
-
-C2OMXNode::C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp)
- : mComp(comp), mFrameIndex(0), mWidth(0), mHeight(0),
- mAdjustTimestampGapUs(0), mFirstInputFrame(true) {
- // TODO: read from intf()
- if (!strncmp(comp->getName().c_str(), "c2.android.", 11)) {
- mUsage = GRALLOC_USAGE_SW_READ_OFTEN;
- } else {
- mUsage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
- }
-}
-
-status_t C2OMXNode::freeNode() {
- mComp.reset();
- return OK;
-}
-
-status_t C2OMXNode::sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
- if (cmd == OMX_CommandStateSet && param == OMX_StateLoaded) {
- // Reset first input frame so if C2OMXNode is recycled, the timestamp does not become
- // negative. This is a workaround for HW codecs that do not handle timestamp rollover.
- mFirstInputFrame = true;
- }
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getParameter(OMX_INDEXTYPE index, void *params, size_t size) {
- status_t err = ERROR_UNSUPPORTED;
- switch ((uint32_t)index) {
- case OMX_IndexParamConsumerUsageBits: {
- OMX_U32 *usage = (OMX_U32 *)params;
- *usage = mUsage;
- err = OK;
- break;
- }
- case OMX_IndexParamPortDefinition: {
- if (size < sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
- return BAD_VALUE;
- }
- OMX_PARAM_PORTDEFINITIONTYPE *pDef = (OMX_PARAM_PORTDEFINITIONTYPE *)params;
- // TODO: read these from intf()
- pDef->nBufferCountActual = 16;
- pDef->eDomain = OMX_PortDomainVideo;
- pDef->format.video.nFrameWidth = mWidth;
- pDef->format.video.nFrameHeight = mHeight;
- err = OK;
- break;
- }
- default:
- break;
- }
- return err;
-}
-
-status_t C2OMXNode::setParameter(OMX_INDEXTYPE index, const void *params, size_t size) {
- // handle max/fixed frame duration control
- if (index == (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl
- && params != NULL
- && size == sizeof(OMX_PARAM_U32TYPE)) {
- // The incoming number is an int32_t contained in OMX_U32.
- mAdjustTimestampGapUs = (int32_t)((OMX_PARAM_U32TYPE*)params)->nU32;
- return OK;
- }
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getConfig(OMX_INDEXTYPE index, void *config, size_t size) {
- (void)index;
- (void)config;
- (void)size;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setConfig(OMX_INDEXTYPE index, const void *config, size_t size) {
- (void)index;
- (void)config;
- (void)size;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
- (void)portIndex;
- (void)mode;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::prepareForAdaptivePlayback(
- OMX_U32 portIndex, OMX_BOOL enable,
- OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
- (void)portIndex;
- (void)enable;
- (void)maxFrameWidth;
- (void)maxFrameHeight;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::configureVideoTunnelMode(
- OMX_U32 portIndex, OMX_BOOL tunneled,
- OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
- (void)portIndex;
- (void)tunneled;
- (void)audioHwSync;
- *sidebandHandle = nullptr;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage) {
- (void)portIndex;
- *usage = 0;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::setInputSurface(const sp<IOMXBufferSource> &bufferSource) {
- c2_status_t err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
- C2PlatformAllocatorStore::GRALLOC,
- &mAllocator);
- if (err != OK) {
- return UNKNOWN_ERROR;
- }
- mBufferSource = bufferSource;
- return OK;
-}
-
-status_t C2OMXNode::allocateSecureBuffer(
- OMX_U32 portIndex, size_t size, buffer_id *buffer,
- void **bufferData, sp<NativeHandle> *nativeHandle) {
- (void)portIndex;
- (void)size;
- (void)nativeHandle;
- *buffer = 0;
- *bufferData = nullptr;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::useBuffer(
- OMX_U32 portIndex, const OMXBuffer &omxBuf, buffer_id *buffer) {
- (void)portIndex;
- (void)omxBuf;
- *buffer = 0;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::freeBuffer(OMX_U32 portIndex, buffer_id buffer) {
- (void)portIndex;
- (void)buffer;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::fillBuffer(
- buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
- (void)buffer;
- (void)omxBuf;
- (void)fenceFd;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::emptyBuffer(
- buffer_id buffer, const OMXBuffer &omxBuf,
- OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
- // TODO: better fence handling
- if (fenceFd >= 0) {
- sp<Fence> fence = new Fence(fenceFd);
- fence->waitForever(LOG_TAG);
- }
- std::shared_ptr<Codec2Client::Component> comp = mComp.lock();
- if (!comp) {
- return NO_INIT;
- }
-
- uint32_t c2Flags = (flags & OMX_BUFFERFLAG_EOS)
- ? C2FrameData::FLAG_END_OF_STREAM : 0;
- std::shared_ptr<C2GraphicBlock> block;
-
- C2Handle *handle = nullptr;
- if (omxBuf.mBufferType == OMXBuffer::kBufferTypeANWBuffer
- && omxBuf.mGraphicBuffer != nullptr) {
- std::shared_ptr<C2GraphicAllocation> alloc;
- handle = WrapNativeCodec2GrallocHandle(
- omxBuf.mGraphicBuffer->handle,
- omxBuf.mGraphicBuffer->width,
- omxBuf.mGraphicBuffer->height,
- omxBuf.mGraphicBuffer->format,
- omxBuf.mGraphicBuffer->usage,
- omxBuf.mGraphicBuffer->stride);
- c2_status_t err = mAllocator->priorGraphicAllocation(handle, &alloc);
- if (err != OK) {
- return UNKNOWN_ERROR;
- }
- block = _C2BlockFactory::CreateGraphicBlock(alloc);
- } else if (!(flags & OMX_BUFFERFLAG_EOS)) {
- return BAD_VALUE;
- }
-
- std::unique_ptr<C2Work> work(new C2Work);
- work->input.flags = (C2FrameData::flags_t)c2Flags;
- work->input.ordinal.timestamp = timestamp;
-
- // WORKAROUND: adjust timestamp based on gapUs
- {
- work->input.ordinal.customOrdinal = timestamp; // save input timestamp
- if (mFirstInputFrame) {
- // grab timestamps on first frame
- mPrevInputTimestamp = timestamp;
- mPrevCodecTimestamp = timestamp;
- mFirstInputFrame = false;
- } else if (mAdjustTimestampGapUs > 0) {
- work->input.ordinal.timestamp =
- mPrevCodecTimestamp
- + c2_min((timestamp - mPrevInputTimestamp).peek(), mAdjustTimestampGapUs);
- } else if (mAdjustTimestampGapUs < 0) {
- work->input.ordinal.timestamp = mPrevCodecTimestamp - mAdjustTimestampGapUs;
- }
- mPrevInputTimestamp = work->input.ordinal.customOrdinal;
- mPrevCodecTimestamp = work->input.ordinal.timestamp;
- ALOGV("adjusting %lld to %lld (gap=%lld)",
- work->input.ordinal.customOrdinal.peekll(),
- work->input.ordinal.timestamp.peekll(),
- (long long)mAdjustTimestampGapUs);
- }
-
- work->input.ordinal.frameIndex = mFrameIndex++;
- work->input.buffers.clear();
- if (block) {
- std::shared_ptr<C2Buffer> c2Buffer(
- // TODO: fence
- new Buffer2D(block->share(
- C2Rect(block->width(), block->height()), ::C2Fence())),
- [buffer, source = getSource()](C2Buffer *ptr) {
- delete ptr;
- // TODO: fence
- (void)source->onInputBufferEmptied(buffer, -1);
- });
- work->input.buffers.push_back(c2Buffer);
- }
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
-
- c2_status_t err = comp->queue(&items);
- if (err != C2_OK) {
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-status_t C2OMXNode::getExtensionIndex(
- const char *parameterName, OMX_INDEXTYPE *index) {
- (void)parameterName;
- *index = OMX_IndexMax;
- return ERROR_UNSUPPORTED;
-}
-
-status_t C2OMXNode::dispatchMessage(const omx_message& msg) {
- if (msg.type != omx_message::EVENT) {
- return ERROR_UNSUPPORTED;
- }
- if (msg.u.event_data.event != OMX_EventDataSpaceChanged) {
- return ERROR_UNSUPPORTED;
- }
- android_dataspace dataSpace = (android_dataspace)msg.u.event_data.data1;
- uint32_t pixelFormat = msg.u.event_data.data3;
-
- // TODO: set dataspace on component to see if it impacts color aspects
- ALOGD("dataspace changed to %#x pixel format: %#x", dataSpace, pixelFormat);
- return OK;
-}
-
-sp<IOMXBufferSource> C2OMXNode::getSource() {
- return mBufferSource;
-}
-
-void C2OMXNode::setFrameSize(uint32_t width, uint32_t height) {
- mWidth = width;
- mHeight = height;
-}
-
-} // namespace android
diff --git a/media/sfplugin/C2OMXNode.h b/media/sfplugin/C2OMXNode.h
deleted file mode 100644
index b5a815e..0000000
--- a/media/sfplugin/C2OMXNode.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef C2_OMX_NODE_H_
-#define C2_OMX_NODE_H_
-
-#include <atomic>
-
-#include <android/IOMXBufferSource.h>
-#include <media/IOMX.h>
-#include <media/OMXBuffer.h>
-#include <codec2/hidl/client.h>
-
-namespace android {
-
-/**
- * IOmxNode implementation around codec 2.0 component, only to be used in
- * IGraphicBufferSource::configure. Only subset of IOmxNode API is implemented
- * and others are left as stub. As a result, one cannot expect this IOmxNode
- * to work in any other usage than IGraphicBufferSource.
- */
-struct C2OMXNode : public BnOMXNode {
- explicit C2OMXNode(const std::shared_ptr<Codec2Client::Component> &comp);
- ~C2OMXNode() override = default;
-
- // IOMXNode
- status_t freeNode() override;
- status_t sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) override;
- status_t getParameter(
- OMX_INDEXTYPE index, void *params, size_t size) override;
- status_t setParameter(
- OMX_INDEXTYPE index, const void *params, size_t size) override;
- status_t getConfig(
- OMX_INDEXTYPE index, void *params, size_t size) override;
- status_t setConfig(
- OMX_INDEXTYPE index, const void *params, size_t size) override;
- status_t setPortMode(OMX_U32 port_index, IOMX::PortMode mode) override;
- status_t prepareForAdaptivePlayback(
- OMX_U32 portIndex, OMX_BOOL enable,
- OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) override;
- status_t configureVideoTunnelMode(
- OMX_U32 portIndex, OMX_BOOL tunneled,
- OMX_U32 audioHwSync, native_handle_t **sidebandHandle) override;
- status_t getGraphicBufferUsage(
- OMX_U32 port_index, OMX_U32* usage) override;
- status_t setInputSurface(
- const sp<IOMXBufferSource> &bufferSource) override;
- status_t allocateSecureBuffer(
- OMX_U32 port_index, size_t size, buffer_id *buffer,
- void **buffer_data, sp<NativeHandle> *native_handle) override;
- status_t useBuffer(
- OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) override;
- status_t freeBuffer(
- OMX_U32 port_index, buffer_id buffer) override;
- status_t fillBuffer(
- buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) override;
- status_t emptyBuffer(
- buffer_id buffer, const OMXBuffer &omxBuf,
- OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) override;
- status_t getExtensionIndex(
- const char *parameter_name,
- OMX_INDEXTYPE *index) override;
- status_t dispatchMessage(const omx_message &msg) override;
-
- sp<IOMXBufferSource> getSource();
- void setFrameSize(uint32_t width, uint32_t height);
-
-private:
- std::weak_ptr<Codec2Client::Component> mComp;
- sp<IOMXBufferSource> mBufferSource;
- std::shared_ptr<C2Allocator> mAllocator;
- std::atomic_uint64_t mFrameIndex;
- uint32_t mWidth;
- uint32_t mHeight;
- uint64_t mUsage;
-
- // WORKAROUND: timestamp adjustment
-
- // if >0: this is the max timestamp gap, if <0: this is -1 times the fixed timestamp gap
- // if 0: no timestamp adjustment is made
- // note that C2OMXNode can be recycled between encoding sessions.
- int32_t mAdjustTimestampGapUs;
- bool mFirstInputFrame; // true for first input
- c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame
- c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame
-};
-
-} // namespace android
-
-#endif // C2_OMX_NODE_H_
diff --git a/media/sfplugin/CCodec.cpp b/media/sfplugin/CCodec.cpp
deleted file mode 100644
index 944a8a5..0000000
--- a/media/sfplugin/CCodec.cpp
+++ /dev/null
@@ -1,1768 +0,0 @@
-/*
- * Copyright (C) 2017 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 "CCodec"
-#include <utils/Log.h>
-
-#include <sstream>
-#include <thread>
-
-#include <C2Config.h>
-#include <C2Debug.h>
-#include <C2ParamInternal.h>
-#include <C2PlatformSupport.h>
-
-#include <android/IGraphicBufferSource.h>
-#include <android/IOMXBufferSource.h>
-#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
-#include <android/hardware/media/omx/1.0/IOmx.h>
-#include <android-base/stringprintf.h>
-#include <cutils/properties.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/Surface.h>
-#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
-#include <media/omx/1.0/WGraphicBufferSource.h>
-#include <media/openmax/OMX_IndexExt.h>
-#include <media/stagefright/BufferProducerWrapper.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/PersistentSurface.h>
-#include <media/stagefright/codec2/1.0/InputSurface.h>
-
-#include "C2OMXNode.h"
-#include "CCodec.h"
-#include "CCodecBufferChannel.h"
-#include "InputSurfaceWrapper.h"
-
-extern "C" android::PersistentSurface *CreateInputSurface();
-
-namespace android {
-
-using namespace std::chrono_literals;
-using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
-using android::base::StringPrintf;
-using BGraphicBufferSource = ::android::IGraphicBufferSource;
-using ::hardware::google::media::c2::V1_0::IInputSurface;
-
-namespace {
-
-class CCodecWatchdog : public AHandler {
-private:
- enum {
- kWhatWatch,
- };
- constexpr static int64_t kWatchIntervalUs = 3300000; // 3.3 secs
-
-public:
- static sp<CCodecWatchdog> getInstance() {
- static sp<CCodecWatchdog> instance(new CCodecWatchdog);
- static std::once_flag flag;
- // Call Init() only once.
- std::call_once(flag, Init, instance);
- return instance;
- }
-
- ~CCodecWatchdog() = default;
-
- void watch(sp<CCodec> codec) {
- bool shouldPost = false;
- {
- Mutexed<std::set<wp<CCodec>>>::Locked codecs(mCodecsToWatch);
- // If a watch message is in flight, piggy-back this instance as well.
- // Otherwise, post a new watch message.
- shouldPost = codecs->empty();
- codecs->emplace(codec);
- }
- if (shouldPost) {
- ALOGV("posting watch message");
- (new AMessage(kWhatWatch, this))->post(kWatchIntervalUs);
- }
- }
-
-protected:
- void onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatWatch: {
- Mutexed<std::set<wp<CCodec>>>::Locked codecs(mCodecsToWatch);
- ALOGV("watch for %zu codecs", codecs->size());
- for (auto it = codecs->begin(); it != codecs->end(); ++it) {
- sp<CCodec> codec = it->promote();
- if (codec == nullptr) {
- continue;
- }
- codec->initiateReleaseIfStuck();
- }
- codecs->clear();
- break;
- }
-
- default: {
- TRESPASS("CCodecWatchdog: unrecognized message");
- }
- }
- }
-
-private:
- CCodecWatchdog() : mLooper(new ALooper) {}
-
- static void Init(const sp<CCodecWatchdog> &thiz) {
- ALOGV("Init");
- thiz->mLooper->setName("CCodecWatchdog");
- thiz->mLooper->registerHandler(thiz);
- thiz->mLooper->start();
- }
-
- sp<ALooper> mLooper;
-
- Mutexed<std::set<wp<CCodec>>> mCodecsToWatch;
-};
-
-class C2InputSurfaceWrapper : public InputSurfaceWrapper {
-public:
- explicit C2InputSurfaceWrapper(
- const std::shared_ptr<Codec2Client::InputSurface> &surface) :
- mSurface(surface) {
- }
-
- ~C2InputSurfaceWrapper() override = default;
-
- status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
- if (mConnection != nullptr) {
- return ALREADY_EXISTS;
- }
- return toStatusT(mSurface->connectToComponent(comp, &mConnection),
- C2_OPERATION_InputSurface_connectToComponent);
- }
-
- void disconnect() override {
- if (mConnection != nullptr) {
- mConnection->disconnect();
- mConnection = nullptr;
- }
- }
-
- status_t start() override {
- // InputSurface does not distinguish started state
- return OK;
- }
-
- status_t signalEndOfInputStream() override {
- C2InputSurfaceEosTuning eos(true);
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = mSurface->getConfigurable()->config({&eos}, C2_MAY_BLOCK, &failures);
- if (err != C2_OK) {
- return UNKNOWN_ERROR;
- }
- return OK;
- }
-
- status_t configure(Config &config __unused) {
- // TODO
- return OK;
- }
-
-private:
- std::shared_ptr<Codec2Client::InputSurface> mSurface;
- std::shared_ptr<Codec2Client::InputSurfaceConnection> mConnection;
-};
-
-class GraphicBufferSourceWrapper : public InputSurfaceWrapper {
-public:
-// explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {}
- GraphicBufferSourceWrapper(
- const sp<BGraphicBufferSource> &source,
- uint32_t width,
- uint32_t height)
- : mSource(source), mWidth(width), mHeight(height) {
- mDataSpace = HAL_DATASPACE_BT709;
- }
- ~GraphicBufferSourceWrapper() override = default;
-
- status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
- mNode = new C2OMXNode(comp);
- mNode->setFrameSize(mWidth, mHeight);
-
- // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
- // communicate that directly to the component.
- mSource->configure(mNode, mDataSpace);
- return OK;
- }
-
- void disconnect() override {
- if (mNode == nullptr) {
- return;
- }
- sp<IOMXBufferSource> source = mNode->getSource();
- if (source == nullptr) {
- ALOGD("GBSWrapper::disconnect: node is not configured with OMXBufferSource.");
- return;
- }
- source->onOmxIdle();
- source->onOmxLoaded();
- mNode.clear();
- }
-
- status_t GetStatus(const binder::Status &status) {
- status_t err = OK;
- if (!status.isOk()) {
- err = status.serviceSpecificErrorCode();
- if (err == OK) {
- err = status.transactionError();
- if (err == OK) {
- // binder status failed, but there is no servie or transaction error
- err = UNKNOWN_ERROR;
- }
- }
- }
- return err;
- }
-
- status_t start() override {
- sp<IOMXBufferSource> source = mNode->getSource();
- if (source == nullptr) {
- return NO_INIT;
- }
- constexpr size_t kNumSlots = 16;
- for (size_t i = 0; i < kNumSlots; ++i) {
- source->onInputBufferAdded(i);
- }
-
- source->onOmxExecuting();
- return OK;
- }
-
- status_t signalEndOfInputStream() override {
- return GetStatus(mSource->signalEndOfInputStream());
- }
-
- status_t configure(Config &config) {
- std::stringstream status;
- status_t err = OK;
-
- // handle each configuration granually, in case we need to handle part of the configuration
- // elsewhere
-
- // TRICKY: we do not unset frame delay repeating
- if (config.mMinFps > 0 && config.mMinFps != mConfig.mMinFps) {
- int64_t us = 1e6 / config.mMinFps + 0.5;
- status_t res = GetStatus(mSource->setRepeatPreviousFrameDelayUs(us));
- status << " minFps=" << config.mMinFps << " => repeatDelayUs=" << us;
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- }
- mConfig.mMinFps = config.mMinFps;
- }
-
- // pts gap
- if (config.mMinAdjustedFps > 0 || config.mFixedAdjustedFps > 0) {
- if (mNode != nullptr) {
- OMX_PARAM_U32TYPE ptrGapParam = {};
- ptrGapParam.nSize = sizeof(OMX_PARAM_U32TYPE);
- ptrGapParam.nU32 = (config.mMinAdjustedFps > 0)
- ? c2_min(INT32_MAX + 0., 1e6 / config.mMinAdjustedFps + 0.5)
- : c2_max(0. - INT32_MAX, -1e6 / config.mFixedAdjustedFps - 0.5);
- (void)mNode->setParameter(
- (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
- &ptrGapParam, sizeof(ptrGapParam));
- }
- }
-
- // max fps
- // TRICKY: we do not unset max fps to 0 unless using fixed fps
- if ((config.mMaxFps > 0 || (config.mFixedAdjustedFps > 0 && config.mMaxFps == 0))
- && config.mMaxFps != mConfig.mMaxFps) {
- status_t res = GetStatus(mSource->setMaxFps(config.mMaxFps));
- status << " maxFps=" << config.mMaxFps;
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- }
- mConfig.mMaxFps = config.mMaxFps;
- }
-
- if (config.mTimeOffsetUs != mConfig.mTimeOffsetUs) {
- status_t res = GetStatus(mSource->setTimeOffsetUs(config.mTimeOffsetUs));
- status << " timeOffset " << config.mTimeOffsetUs << "us";
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- }
- mConfig.mTimeOffsetUs = config.mTimeOffsetUs;
- }
-
- if (config.mCaptureFps != mConfig.mCaptureFps || config.mCodedFps != mConfig.mCodedFps) {
- status_t res =
- GetStatus(mSource->setTimeLapseConfig(config.mCodedFps, config.mCaptureFps));
- status << " timeLapse " << config.mCaptureFps << "fps as " << config.mCodedFps << "fps";
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- }
- mConfig.mCaptureFps = config.mCaptureFps;
- mConfig.mCodedFps = config.mCodedFps;
- }
-
- if (config.mStartAtUs != mConfig.mStartAtUs
- || (config.mStopped != mConfig.mStopped && !config.mStopped)) {
- status_t res = GetStatus(mSource->setStartTimeUs(config.mStartAtUs));
- status << " start at " << config.mStartAtUs << "us";
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- }
- mConfig.mStartAtUs = config.mStartAtUs;
- mConfig.mStopped = config.mStopped;
- }
-
- // suspend-resume
- if (config.mSuspended != mConfig.mSuspended) {
- status_t res = GetStatus(mSource->setSuspend(config.mSuspended, config.mSuspendAtUs));
- status << " " << (config.mSuspended ? "suspend" : "resume")
- << " at " << config.mSuspendAtUs << "us";
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- }
- mConfig.mSuspended = config.mSuspended;
- mConfig.mSuspendAtUs = config.mSuspendAtUs;
- }
-
- if (config.mStopped != mConfig.mStopped && config.mStopped) {
- status_t res = GetStatus(mSource->setStopTimeUs(config.mStopAtUs));
- status << " stop at " << config.mStopAtUs << "us";
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- err = res;
- } else {
- status << " delayUs";
- res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs));
- if (res != OK) {
- status << " (=> " << asString(res) << ")";
- } else {
- status << "=" << config.mInputDelayUs << "us";
- }
- mConfig.mInputDelayUs = config.mInputDelayUs;
- }
- mConfig.mStopAtUs = config.mStopAtUs;
- mConfig.mStopped = config.mStopped;
- }
-
- // color aspects (android._color-aspects)
-
- // consumer usage
- ALOGD("ISConfig%s", status.str().c_str());
- return err;
- }
-
-private:
- sp<BGraphicBufferSource> mSource;
- sp<C2OMXNode> mNode;
- uint32_t mWidth;
- uint32_t mHeight;
- Config mConfig;
-};
-
-class Codec2ClientInterfaceWrapper : public C2ComponentStore {
- std::shared_ptr<Codec2Client> mClient;
-
-public:
- Codec2ClientInterfaceWrapper(std::shared_ptr<Codec2Client> client)
- : mClient(client) { }
-
- virtual ~Codec2ClientInterfaceWrapper() = default;
-
- virtual c2_status_t config_sm(
- const std::vector<C2Param *> &params,
- std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
- return mClient->config(params, C2_MAY_BLOCK, failures);
- };
-
- virtual c2_status_t copyBuffer(
- std::shared_ptr<C2GraphicBuffer>,
- std::shared_ptr<C2GraphicBuffer>) {
- return C2_OMITTED;
- }
-
- virtual c2_status_t createComponent(
- C2String, std::shared_ptr<C2Component> *const component) {
- component->reset();
- return C2_OMITTED;
- }
-
- virtual c2_status_t createInterface(
- C2String, std::shared_ptr<C2ComponentInterface> *const interface) {
- interface->reset();
- return C2_OMITTED;
- }
-
- virtual c2_status_t query_sm(
- const std::vector<C2Param *> &stackParams,
- const std::vector<C2Param::Index> &heapParamIndices,
- std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
- return mClient->query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
- }
-
- virtual c2_status_t querySupportedParams_nb(
- std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
- return mClient->querySupportedParams(params);
- }
-
- virtual c2_status_t querySupportedValues_sm(
- std::vector<C2FieldSupportedValuesQuery> &fields) const {
- return mClient->querySupportedValues(fields, C2_MAY_BLOCK);
- }
-
- virtual C2String getName() const {
- return mClient->getName();
- }
-
- virtual std::shared_ptr<C2ParamReflector> getParamReflector() const {
- return mClient->getParamReflector();
- }
-
- virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() {
- return std::vector<std::shared_ptr<const C2Component::Traits>>();
- }
-};
-
-} // namespace
-
-// CCodec::ClientListener
-
-struct CCodec::ClientListener : public Codec2Client::Listener {
-
- explicit ClientListener(const wp<CCodec> &codec) : mCodec(codec) {}
-
- virtual void onWorkDone(
- const std::weak_ptr<Codec2Client::Component>& component,
- std::list<std::unique_ptr<C2Work>>& workItems,
- size_t numDiscardedInputBuffers) override {
- (void)component;
- sp<CCodec> codec(mCodec.promote());
- if (!codec) {
- return;
- }
- codec->onWorkDone(workItems, numDiscardedInputBuffers);
- }
-
- virtual void onTripped(
- const std::weak_ptr<Codec2Client::Component>& component,
- const std::vector<std::shared_ptr<C2SettingResult>>& settingResult
- ) override {
- // TODO
- (void)component;
- (void)settingResult;
- }
-
- virtual void onError(
- const std::weak_ptr<Codec2Client::Component>& component,
- uint32_t errorCode) override {
- // TODO
- (void)component;
- (void)errorCode;
- }
-
- virtual void onDeath(
- const std::weak_ptr<Codec2Client::Component>& component) override {
- { // Log the death of the component.
- std::shared_ptr<Codec2Client::Component> comp = component.lock();
- if (!comp) {
- ALOGE("Codec2 component died.");
- } else {
- ALOGE("Codec2 component \"%s\" died.", comp->getName().c_str());
- }
- }
-
- // Report to MediaCodec.
- sp<CCodec> codec(mCodec.promote());
- if (!codec || !codec->mCallback) {
- return;
- }
- codec->mCallback->onError(DEAD_OBJECT, ACTION_CODE_FATAL);
- }
-
- virtual void onFramesRendered(
- const std::vector<RenderedFrame>& renderedFrames) override {
- // TODO
- (void)renderedFrames;
- }
-
- virtual void onInputBufferDone(
- const std::shared_ptr<C2Buffer>& buffer) override {
- sp<CCodec> codec(mCodec.promote());
- if (codec) {
- codec->onInputBufferDone(buffer);
- }
- }
-
-private:
- wp<CCodec> mCodec;
-};
-
-// CCodecCallbackImpl
-
-class CCodecCallbackImpl : public CCodecCallback {
-public:
- explicit CCodecCallbackImpl(CCodec *codec) : mCodec(codec) {}
- ~CCodecCallbackImpl() override = default;
-
- void onError(status_t err, enum ActionCode actionCode) override {
- mCodec->mCallback->onError(err, actionCode);
- }
-
- void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) override {
- mCodec->mCallback->onOutputFramesRendered(
- {RenderedFrameInfo(mediaTimeUs, renderTimeNs)});
- }
-
- void onWorkQueued(bool eos) override {
- mCodec->onWorkQueued(eos);
- }
-
- void onOutputBuffersChanged() override {
- mCodec->mCallback->onOutputBuffersChanged();
- }
-
-private:
- CCodec *mCodec;
-};
-
-// CCodec
-
-CCodec::CCodec()
- : mChannel(new CCodecBufferChannel(std::make_shared<CCodecCallbackImpl>(this))),
- mQueuedWorkCount(0) {
-}
-
-CCodec::~CCodec() {
-}
-
-std::shared_ptr<BufferChannelBase> CCodec::getBufferChannel() {
- return mChannel;
-}
-
-status_t CCodec::tryAndReportOnError(std::function<status_t()> job) {
- status_t err = job();
- if (err != C2_OK) {
- mCallback->onError(err, ACTION_CODE_FATAL);
- }
- return err;
-}
-
-void CCodec::initiateAllocateComponent(const sp<AMessage> &msg) {
- auto setAllocating = [this] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != RELEASED) {
- return INVALID_OPERATION;
- }
- state->set(ALLOCATING);
- return OK;
- };
- if (tryAndReportOnError(setAllocating) != OK) {
- return;
- }
-
- sp<RefBase> codecInfo;
- CHECK(msg->findObject("codecInfo", &codecInfo));
- // For Codec 2.0 components, componentName == codecInfo->getCodecName().
-
- sp<AMessage> allocMsg(new AMessage(kWhatAllocate, this));
- allocMsg->setObject("codecInfo", codecInfo);
- allocMsg->post();
-}
-
-void CCodec::allocate(const sp<MediaCodecInfo> &codecInfo) {
- if (codecInfo == nullptr) {
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- return;
- }
- ALOGD("allocate(%s)", codecInfo->getCodecName());
- mClientListener.reset(new ClientListener(this));
-
- AString componentName = codecInfo->getCodecName();
- std::shared_ptr<Codec2Client> client;
-
- // set up preferred component store to access vendor store parameters
- client = Codec2Client::CreateFromService("default", false);
- if (client) {
- ALOGI("setting up '%s' as default (vendor) store", client->getInstanceName().c_str());
- SetPreferredCodec2ComponentStore(
- std::make_shared<Codec2ClientInterfaceWrapper>(client));
- }
-
- std::shared_ptr<Codec2Client::Component> comp =
- Codec2Client::CreateComponentByName(
- componentName.c_str(),
- mClientListener,
- &client);
- if (!comp) {
- ALOGE("Failed Create component: %s", componentName.c_str());
- Mutexed<State>::Locked state(mState);
- state->set(RELEASED);
- state.unlock();
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- state.lock();
- return;
- }
- ALOGI("Created component [%s]", componentName.c_str());
- mChannel->setComponent(comp);
- auto setAllocated = [this, comp, client] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != ALLOCATING) {
- state->set(RELEASED);
- return UNKNOWN_ERROR;
- }
- state->set(ALLOCATED);
- state->comp = comp;
- mClient = client;
- return OK;
- };
- if (tryAndReportOnError(setAllocated) != OK) {
- return;
- }
-
- // initialize config here in case setParameters is called prior to configure
- Mutexed<Config>::Locked config(mConfig);
- status_t err = config->initialize(mClient, comp);
- if (err != OK) {
- ALOGW("Failed to initialize configuration support");
- // TODO: report error once we complete implementation.
- }
- config->queryConfiguration(comp);
-
- mCallback->onComponentAllocated(componentName.c_str());
-}
-
-void CCodec::initiateConfigureComponent(const sp<AMessage> &format) {
- auto checkAllocated = [this] {
- Mutexed<State>::Locked state(mState);
- return (state->get() != ALLOCATED) ? UNKNOWN_ERROR : OK;
- };
- if (tryAndReportOnError(checkAllocated) != OK) {
- return;
- }
-
- sp<AMessage> msg(new AMessage(kWhatConfigure, this));
- msg->setMessage("format", format);
- msg->post();
-}
-
-void CCodec::configure(const sp<AMessage> &msg) {
- std::shared_ptr<Codec2Client::Component> comp;
- auto checkAllocated = [this, &comp] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != ALLOCATED) {
- state->set(RELEASED);
- return UNKNOWN_ERROR;
- }
- comp = state->comp;
- return OK;
- };
- if (tryAndReportOnError(checkAllocated) != OK) {
- return;
- }
-
- auto doConfig = [msg, comp, this]() -> status_t {
- AString mime;
- if (!msg->findString("mime", &mime)) {
- return BAD_VALUE;
- }
-
- int32_t encoder;
- if (!msg->findInt32("encoder", &encoder)) {
- encoder = false;
- }
-
- // TODO: read from intf()
- if ((!encoder) != (comp->getName().find("encoder") == std::string::npos)) {
- return UNKNOWN_ERROR;
- }
-
- int32_t storeMeta;
- if (encoder
- && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
- && storeMeta != kMetadataBufferTypeInvalid) {
- if (storeMeta != kMetadataBufferTypeANWBuffer) {
- ALOGD("Only ANW buffers are supported for legacy metadata mode");
- return BAD_VALUE;
- }
- mChannel->setMetaMode(CCodecBufferChannel::MODE_ANW);
- }
-
- sp<RefBase> obj;
- sp<Surface> surface;
- if (msg->findObject("native-window", &obj)) {
- surface = static_cast<Surface *>(obj.get());
- setSurface(surface);
- }
-
- Mutexed<Config>::Locked config(mConfig);
- config->mUsingSurface = surface != nullptr;
-
- /*
- * Handle input surface configuration
- */
- if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
- && (config->mDomain & Config::IS_ENCODER)) {
- config->mISConfig.reset(new InputSurfaceWrapper::Config{});
- {
- config->mISConfig->mMinFps = 0;
- int64_t value;
- if (msg->findInt64("repeat-previous-frame-after", &value) && value > 0) {
- config->mISConfig->mMinFps = 1e6 / value;
- }
- (void)msg->findFloat("max-fps-to-encoder", &config->mISConfig->mMaxFps);
- config->mISConfig->mMinAdjustedFps = 0;
- config->mISConfig->mFixedAdjustedFps = 0;
- if (msg->findInt64("max-pts-gap-to-encoder", &value)) {
- if (value < 0 && value >= INT32_MIN) {
- config->mISConfig->mFixedAdjustedFps = -1e6 / value;
- } else if (value > 0 && value <= INT32_MAX) {
- config->mISConfig->mMinAdjustedFps = 1e6 / value;
- }
- }
- }
-
- {
- double value;
- if (msg->findDouble("time-lapse-fps", &value)) {
- config->mISConfig->mCaptureFps = value;
- (void)msg->findAsFloat(KEY_FRAME_RATE, &config->mISConfig->mCodedFps);
- }
- }
-
- {
- config->mISConfig->mSuspended = false;
- config->mISConfig->mSuspendAtUs = -1;
- int32_t value;
- if (msg->findInt32("create-input-buffers-suspended", &value) && value) {
- config->mISConfig->mSuspended = true;
- }
- }
- }
-
- /*
- * Handle desired color format.
- */
- if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
- int32_t format = -1;
- if (!msg->findInt32(KEY_COLOR_FORMAT, &format)) {
- /*
- * Also handle default color format (encoders require color format, so this is only
- * needed for decoders.
- */
- if (!(config->mDomain & Config::IS_ENCODER)) {
- format = (surface == nullptr) ? COLOR_FormatYUV420Planar : COLOR_FormatSurface;
- }
- }
-
- if (format >= 0) {
- msg->setInt32("android._color-format", format);
- }
- }
-
- std::vector<std::unique_ptr<C2Param>> configUpdate;
- status_t err = config->getConfigUpdateFromSdkParams(
- comp, msg, Config::IS_CONFIG, C2_DONT_BLOCK, &configUpdate);
- if (err != OK) {
- ALOGW("failed to convert configuration to c2 params");
- }
- err = config->setParameters(comp, configUpdate, C2_DONT_BLOCK);
- if (err != OK) {
- ALOGW("failed to configure c2 params");
- return err;
- }
-
- std::vector<std::unique_ptr<C2Param>> params;
- C2StreamUsageTuning::input usage(0u, 0u);
- C2StreamMaxBufferSizeInfo::input maxInputSize(0u, 0u);
-
- std::initializer_list<C2Param::Index> indices {
- };
- c2_status_t c2err = comp->query(
- { &usage, &maxInputSize },
- indices,
- C2_DONT_BLOCK,
- &params);
- if (c2err != C2_OK && c2err != C2_BAD_INDEX) {
- ALOGE("Failed to query component interface: %d", c2err);
- return UNKNOWN_ERROR;
- }
- if (params.size() != indices.size()) {
- ALOGE("Component returns wrong number of params: expected %zu actual %zu",
- indices.size(), params.size());
- return UNKNOWN_ERROR;
- }
- if (usage && (usage.value & C2MemoryUsage::CPU_READ)) {
- config->mInputFormat->setInt32("using-sw-read-often", true);
- }
-
- // NOTE: we don't blindly use client specified input size if specified as clients
- // at times specify too small size. Instead, mimic the behavior from OMX, where the
- // client specified size is only used to ask for bigger buffers than component suggested
- // size.
- int32_t clientInputSize = 0;
- bool clientSpecifiedInputSize =
- msg->findInt32(KEY_MAX_INPUT_SIZE, &clientInputSize) && clientInputSize > 0;
- // TEMP: enforce minimum buffer size of 1MB for video decoders
- // and 16K / 4K for audio encoders/decoders
- if (maxInputSize.value == 0) {
- if (config->mDomain & Config::IS_AUDIO) {
- maxInputSize.value = encoder ? 16384 : 4096;
- } else if (!encoder) {
- maxInputSize.value = 1048576u;
- }
- }
-
- // verify that CSD fits into this size (if defined)
- if ((config->mDomain & Config::IS_DECODER) && maxInputSize.value > 0) {
- sp<ABuffer> csd;
- for (size_t ix = 0; msg->findBuffer(StringPrintf("csd-%zu", ix).c_str(), &csd); ++ix) {
- if (csd && csd->size() > maxInputSize.value) {
- maxInputSize.value = csd->size();
- }
- }
- }
-
- // TODO: do this based on component requiring linear allocator for input
- if ((config->mDomain & Config::IS_DECODER) || (config->mDomain & Config::IS_AUDIO)) {
- if (clientSpecifiedInputSize) {
- // Warn that we're overriding client's max input size if necessary.
- if ((uint32_t)clientInputSize < maxInputSize.value) {
- ALOGD("client requested max input size %d, which is smaller than "
- "what component recommended (%u); overriding with component "
- "recommendation.", clientInputSize, maxInputSize.value);
- ALOGW("This behavior is subject to change. It is recommended that "
- "app developers double check whether the requested "
- "max input size is in reasonable range.");
- } else {
- maxInputSize.value = clientInputSize;
- }
- }
- // Pass max input size on input format to the buffer channel (if supplied by the
- // component or by a default)
- if (maxInputSize.value) {
- config->mInputFormat->setInt32(
- KEY_MAX_INPUT_SIZE,
- (int32_t)(c2_min(maxInputSize.value, uint32_t(INT32_MAX))));
- }
- }
-
- if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))) {
- // propagate HDR static info to output format for both encoders and decoders
- // if component supports this info, we will update from component, but only the raw port,
- // so don't propagate if component already filled it in.
- sp<ABuffer> hdrInfo;
- if (msg->findBuffer(KEY_HDR_STATIC_INFO, &hdrInfo)
- && !config->mOutputFormat->findBuffer(KEY_HDR_STATIC_INFO, &hdrInfo)) {
- config->mOutputFormat->setBuffer(KEY_HDR_STATIC_INFO, hdrInfo);
- }
-
- // Set desired color format from configuration parameter
- int32_t format;
- if (msg->findInt32("android._color-format", &format)) {
- if (config->mDomain & Config::IS_ENCODER) {
- config->mInputFormat->setInt32(KEY_COLOR_FORMAT, format);
- } else {
- config->mOutputFormat->setInt32(KEY_COLOR_FORMAT, format);
- }
- }
- }
-
- // propagate encoder delay and padding to output format
- if ((config->mDomain & Config::IS_DECODER) && (config->mDomain & Config::IS_AUDIO)) {
- int delay = 0;
- if (msg->findInt32("encoder-delay", &delay)) {
- config->mOutputFormat->setInt32("encoder-delay", delay);
- }
- int padding = 0;
- if (msg->findInt32("encoder-padding", &padding)) {
- config->mOutputFormat->setInt32("encoder-padding", padding);
- }
- }
-
- // set channel-mask
- if (config->mDomain & Config::IS_AUDIO) {
- int32_t mask;
- if (msg->findInt32(KEY_CHANNEL_MASK, &mask)) {
- if (config->mDomain & Config::IS_ENCODER) {
- config->mInputFormat->setInt32(KEY_CHANNEL_MASK, mask);
- } else {
- config->mOutputFormat->setInt32(KEY_CHANNEL_MASK, mask);
- }
- }
- }
-
- ALOGD("setup formats input: %s and output: %s",
- config->mInputFormat->debugString().c_str(),
- config->mOutputFormat->debugString().c_str());
- return OK;
- };
- if (tryAndReportOnError(doConfig) != OK) {
- return;
- }
-
- Mutexed<Config>::Locked config(mConfig);
-
- mCallback->onComponentConfigured(config->mInputFormat, config->mOutputFormat);
-}
-
-void CCodec::initiateCreateInputSurface() {
- status_t err = [this] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != ALLOCATED) {
- return UNKNOWN_ERROR;
- }
- // TODO: read it from intf() properly.
- if (state->comp->getName().find("encoder") == std::string::npos) {
- return INVALID_OPERATION;
- }
- return OK;
- }();
- if (err != OK) {
- mCallback->onInputSurfaceCreationFailed(err);
- return;
- }
-
- (new AMessage(kWhatCreateInputSurface, this))->post();
-}
-
-void CCodec::createInputSurface() {
- status_t err;
- sp<IGraphicBufferProducer> bufferProducer;
-
- sp<AMessage> inputFormat;
- sp<AMessage> outputFormat;
- {
- Mutexed<Config>::Locked config(mConfig);
- inputFormat = config->mInputFormat;
- outputFormat = config->mOutputFormat;
- }
-
- std::shared_ptr<PersistentSurface> persistentSurface(CreateInputSurface());
-
- if (persistentSurface->getHidlTarget()) {
- sp<IInputSurface> inputSurface = IInputSurface::castFrom(
- persistentSurface->getHidlTarget());
- if (!inputSurface) {
- ALOGE("Corrupted input surface");
- mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR);
- return;
- }
- err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
- std::make_shared<Codec2Client::InputSurface>(inputSurface)));
- bufferProducer = new H2BGraphicBufferProducer(inputSurface);
- } else {
- int32_t width = 0;
- (void)outputFormat->findInt32("width", &width);
- int32_t height = 0;
- (void)outputFormat->findInt32("height", &height);
- err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
- persistentSurface->getBufferSource(), width, height));
- bufferProducer = persistentSurface->getBufferProducer();
- }
-
- if (err != OK) {
- ALOGE("Failed to set up input surface: %d", err);
- mCallback->onInputSurfaceCreationFailed(err);
- return;
- }
-
- mCallback->onInputSurfaceCreated(
- inputFormat,
- outputFormat,
- new BufferProducerWrapper(bufferProducer));
-}
-
-status_t CCodec::setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface) {
- Mutexed<Config>::Locked config(mConfig);
- config->mUsingSurface = true;
-
- // we are now using surface - apply default color aspects to input format - as well as
- // get dataspace
- bool inputFormatChanged = config->updateFormats(config->IS_INPUT);
- ALOGD("input format %s to %s",
- inputFormatChanged ? "changed" : "unchanged",
- config->mInputFormat->debugString().c_str());
-
- // configure dataspace
- static_assert(sizeof(int32_t) == sizeof(android_dataspace), "dataspace size mismatch");
- android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
- (void)config->mInputFormat->findInt32("android._dataspace", (int32_t*)&dataSpace);
- surface->setDataSpace(dataSpace);
-
- status_t err = mChannel->setInputSurface(surface);
- if (err != OK) {
- // undo input format update
- config->mUsingSurface = false;
- (void)config->updateFormats(config->IS_INPUT);
- return err;
- }
- config->mInputSurface = surface;
-
- if (config->mISConfig) {
- surface->configure(*config->mISConfig);
- } else {
- ALOGD("ISConfig: no configuration");
- }
-
- return OK;
-}
-
-void CCodec::initiateSetInputSurface(const sp<PersistentSurface> &surface) {
- sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
- msg->setObject("surface", surface);
- msg->post();
-}
-
-void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
- sp<AMessage> inputFormat;
- sp<AMessage> outputFormat;
- {
- Mutexed<Config>::Locked config(mConfig);
- inputFormat = config->mInputFormat;
- outputFormat = config->mOutputFormat;
- }
- auto hidlTarget = surface->getHidlTarget();
- if (hidlTarget) {
- sp<IInputSurface> inputSurface =
- IInputSurface::castFrom(hidlTarget);
- if (!inputSurface) {
- ALOGE("Failed to set input surface: Corrupted surface.");
- mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR);
- return;
- }
- status_t err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
- std::make_shared<Codec2Client::InputSurface>(inputSurface)));
- if (err != OK) {
- ALOGE("Failed to set up input surface: %d", err);
- mCallback->onInputSurfaceDeclined(err);
- return;
- }
- } else {
- int32_t width = 0;
- (void)outputFormat->findInt32("width", &width);
- int32_t height = 0;
- (void)outputFormat->findInt32("height", &height);
- status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
- surface->getBufferSource(), width, height));
- if (err != OK) {
- ALOGE("Failed to set up input surface: %d", err);
- mCallback->onInputSurfaceDeclined(err);
- return;
- }
- }
- mCallback->onInputSurfaceAccepted(inputFormat, outputFormat);
-}
-
-void CCodec::initiateStart() {
- auto setStarting = [this] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != ALLOCATED) {
- return UNKNOWN_ERROR;
- }
- state->set(STARTING);
- return OK;
- };
- if (tryAndReportOnError(setStarting) != OK) {
- return;
- }
-
- (new AMessage(kWhatStart, this))->post();
-}
-
-void CCodec::start() {
- std::shared_ptr<Codec2Client::Component> comp;
- auto checkStarting = [this, &comp] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != STARTING) {
- return UNKNOWN_ERROR;
- }
- comp = state->comp;
- return OK;
- };
- if (tryAndReportOnError(checkStarting) != OK) {
- return;
- }
-
- c2_status_t err = comp->start();
- if (err != C2_OK) {
- mCallback->onError(toStatusT(err, C2_OPERATION_Component_start),
- ACTION_CODE_FATAL);
- return;
- }
- sp<AMessage> inputFormat;
- sp<AMessage> outputFormat;
- status_t err2 = OK;
- {
- Mutexed<Config>::Locked config(mConfig);
- inputFormat = config->mInputFormat;
- outputFormat = config->mOutputFormat;
- if (config->mInputSurface) {
- err2 = config->mInputSurface->start();
- }
- }
- if (err2 != OK) {
- mCallback->onError(err2, ACTION_CODE_FATAL);
- return;
- }
- err2 = mChannel->start(inputFormat, outputFormat);
- if (err2 != OK) {
- mCallback->onError(err2, ACTION_CODE_FATAL);
- return;
- }
-
- auto setRunning = [this] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != STARTING) {
- return UNKNOWN_ERROR;
- }
- state->set(RUNNING);
- return OK;
- };
- if (tryAndReportOnError(setRunning) != OK) {
- return;
- }
- mCallback->onStartCompleted();
-
- (void)mChannel->requestInitialInputBuffers();
-}
-
-void CCodec::initiateShutdown(bool keepComponentAllocated) {
- if (keepComponentAllocated) {
- initiateStop();
- } else {
- initiateRelease();
- }
-}
-
-void CCodec::initiateStop() {
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() == ALLOCATED
- || state->get() == RELEASED
- || state->get() == STOPPING
- || state->get() == RELEASING) {
- // We're already stopped, released, or doing it right now.
- state.unlock();
- mCallback->onStopCompleted();
- state.lock();
- return;
- }
- state->set(STOPPING);
- }
-
- mChannel->stop();
- (new AMessage(kWhatStop, this))->post();
-}
-
-void CCodec::stop() {
- std::shared_ptr<Codec2Client::Component> comp;
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() == RELEASING) {
- state.unlock();
- // We're already stopped or release is in progress.
- mCallback->onStopCompleted();
- state.lock();
- return;
- } else if (state->get() != STOPPING) {
- state.unlock();
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- state.lock();
- return;
- }
- comp = state->comp;
- }
- status_t err = comp->stop();
- if (err != C2_OK) {
- // TODO: convert err into status_t
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- }
-
- {
- Mutexed<Config>::Locked config(mConfig);
- if (config->mInputSurface) {
- config->mInputSurface->disconnect();
- config->mInputSurface = nullptr;
- }
- }
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() == STOPPING) {
- state->set(ALLOCATED);
- }
- }
- mCallback->onStopCompleted();
-}
-
-void CCodec::initiateRelease(bool sendCallback /* = true */) {
- bool clearInputSurfaceIfNeeded = false;
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() == RELEASED || state->get() == RELEASING) {
- // We're already released or doing it right now.
- if (sendCallback) {
- state.unlock();
- mCallback->onReleaseCompleted();
- state.lock();
- }
- return;
- }
- if (state->get() == ALLOCATING) {
- state->set(RELEASING);
- // With the altered state allocate() would fail and clean up.
- if (sendCallback) {
- state.unlock();
- mCallback->onReleaseCompleted();
- state.lock();
- }
- return;
- }
- if (state->get() == STARTING
- || state->get() == RUNNING
- || state->get() == STOPPING) {
- // Input surface may have been started, so clean up is needed.
- clearInputSurfaceIfNeeded = true;
- }
- state->set(RELEASING);
- }
-
- if (clearInputSurfaceIfNeeded) {
- Mutexed<Config>::Locked config(mConfig);
- if (config->mInputSurface) {
- config->mInputSurface->disconnect();
- config->mInputSurface = nullptr;
- }
- }
-
- mChannel->stop();
- // thiz holds strong ref to this while the thread is running.
- sp<CCodec> thiz(this);
- std::thread([thiz, sendCallback] { thiz->release(sendCallback); }).detach();
-}
-
-void CCodec::release(bool sendCallback) {
- std::shared_ptr<Codec2Client::Component> comp;
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() == RELEASED) {
- if (sendCallback) {
- state.unlock();
- mCallback->onReleaseCompleted();
- state.lock();
- }
- return;
- }
- comp = state->comp;
- }
- comp->release();
-
- {
- Mutexed<State>::Locked state(mState);
- state->set(RELEASED);
- state->comp.reset();
- }
- if (sendCallback) {
- mCallback->onReleaseCompleted();
- }
-}
-
-status_t CCodec::setSurface(const sp<Surface> &surface) {
- return mChannel->setSurface(surface);
-}
-
-void CCodec::signalFlush() {
- status_t err = [this] {
- Mutexed<State>::Locked state(mState);
- if (state->get() == FLUSHED) {
- return ALREADY_EXISTS;
- }
- if (state->get() != RUNNING) {
- return UNKNOWN_ERROR;
- }
- state->set(FLUSHING);
- return OK;
- }();
- switch (err) {
- case ALREADY_EXISTS:
- mCallback->onFlushCompleted();
- return;
- case OK:
- break;
- default:
- mCallback->onError(err, ACTION_CODE_FATAL);
- return;
- }
-
- mChannel->stop();
- (new AMessage(kWhatFlush, this))->post();
-}
-
-void CCodec::flush() {
- std::shared_ptr<Codec2Client::Component> comp;
- auto checkFlushing = [this, &comp] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != FLUSHING) {
- return UNKNOWN_ERROR;
- }
- comp = state->comp;
- return OK;
- };
- if (tryAndReportOnError(checkFlushing) != OK) {
- return;
- }
-
- std::list<std::unique_ptr<C2Work>> flushedWork;
- c2_status_t err = comp->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
- {
- Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
- flushedWork.splice(flushedWork.end(), *queue);
- }
- if (err != C2_OK) {
- // TODO: convert err into status_t
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- }
-
- mChannel->flush(flushedWork);
- subQueuedWorkCount(flushedWork.size());
-
- {
- Mutexed<State>::Locked state(mState);
- state->set(FLUSHED);
- }
- mCallback->onFlushCompleted();
-}
-
-void CCodec::signalResume() {
- auto setResuming = [this] {
- Mutexed<State>::Locked state(mState);
- if (state->get() != FLUSHED) {
- return UNKNOWN_ERROR;
- }
- state->set(RESUMING);
- return OK;
- };
- if (tryAndReportOnError(setResuming) != OK) {
- return;
- }
-
- (void)mChannel->start(nullptr, nullptr);
-
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() != RESUMING) {
- state.unlock();
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- state.lock();
- return;
- }
- state->set(RUNNING);
- }
-
- (void)mChannel->requestInitialInputBuffers();
-}
-
-void CCodec::signalSetParameters(const sp<AMessage> &params) {
- setParameters(params);
-}
-
-void CCodec::setParameters(const sp<AMessage> &params) {
- std::shared_ptr<Codec2Client::Component> comp;
- auto checkState = [this, &comp] {
- Mutexed<State>::Locked state(mState);
- if (state->get() == RELEASED) {
- return INVALID_OPERATION;
- }
- comp = state->comp;
- return OK;
- };
- if (tryAndReportOnError(checkState) != OK) {
- return;
- }
-
- Mutexed<Config>::Locked config(mConfig);
-
- /**
- * Handle input surface parameters
- */
- if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
- && (config->mDomain & Config::IS_ENCODER) && config->mInputSurface && config->mISConfig) {
- (void)params->findInt64("time-offset-us", &config->mISConfig->mTimeOffsetUs);
-
- if (params->findInt64("skip-frames-before", &config->mISConfig->mStartAtUs)) {
- config->mISConfig->mStopped = false;
- } else if (params->findInt64("stop-time-us", &config->mISConfig->mStopAtUs)) {
- config->mISConfig->mStopped = true;
- }
-
- int32_t value;
- if (params->findInt32("drop-input-frames", &value)) {
- config->mISConfig->mSuspended = value;
- config->mISConfig->mSuspendAtUs = -1;
- (void)params->findInt64("drop-start-time-us", &config->mISConfig->mSuspendAtUs);
- }
-
- (void)config->mInputSurface->configure(*config->mISConfig);
- if (config->mISConfig->mStopped) {
- config->mInputFormat->setInt64(
- "android._stop-time-offset-us", config->mISConfig->mInputDelayUs);
- }
- }
-
- std::vector<std::unique_ptr<C2Param>> configUpdate;
- (void)config->getConfigUpdateFromSdkParams(
- comp, params, Config::IS_PARAM, C2_MAY_BLOCK, &configUpdate);
- // Prefer to pass parameters to the buffer channel, so they can be synchronized with the frames.
- // Parameter synchronization is not defined when using input surface. For now, route
- // these directly to the component.
- if (config->mInputSurface == nullptr
- && (property_get_bool("debug.stagefright.ccodec_delayed_params", false)
- || comp->getName().find("c2.android.") == 0)) {
- mChannel->setParameters(configUpdate);
- } else {
- (void)config->setParameters(comp, configUpdate, C2_MAY_BLOCK);
- }
-}
-
-void CCodec::signalEndOfInputStream() {
- mCallback->onSignaledInputEOS(mChannel->signalEndOfInputStream());
-}
-
-void CCodec::signalRequestIDRFrame() {
- std::shared_ptr<Codec2Client::Component> comp;
- {
- Mutexed<State>::Locked state(mState);
- if (state->get() == RELEASED) {
- ALOGD("no IDR request sent since component is released");
- return;
- }
- comp = state->comp;
- }
- ALOGV("request IDR");
- Mutexed<Config>::Locked config(mConfig);
- std::vector<std::unique_ptr<C2Param>> params;
- params.push_back(
- std::make_unique<C2StreamRequestSyncFrameTuning::output>(0u, true));
- config->setParameters(comp, params, C2_MAY_BLOCK);
-}
-
-void CCodec::onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems,
- size_t numDiscardedInputBuffers) {
- if (!workItems.empty()) {
- {
- Mutexed<std::list<size_t>>::Locked numDiscardedInputBuffersQueue(
- mNumDiscardedInputBuffersQueue);
- numDiscardedInputBuffersQueue->insert(
- numDiscardedInputBuffersQueue->end(),
- workItems.size() - 1, 0);
- numDiscardedInputBuffersQueue->emplace_back(
- numDiscardedInputBuffers);
- }
- {
- Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
- queue->splice(queue->end(), workItems);
- }
- }
- (new AMessage(kWhatWorkDone, this))->post();
-}
-
-void CCodec::onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer) {
- mChannel->onInputBufferDone(buffer);
-}
-
-void CCodec::onMessageReceived(const sp<AMessage> &msg) {
- TimePoint now = std::chrono::steady_clock::now();
- CCodecWatchdog::getInstance()->watch(this);
- switch (msg->what()) {
- case kWhatAllocate: {
- // C2ComponentStore::createComponent() should return within 100ms.
- setDeadline(now, 150ms, "allocate");
- sp<RefBase> obj;
- CHECK(msg->findObject("codecInfo", &obj));
- allocate((MediaCodecInfo *)obj.get());
- break;
- }
- case kWhatConfigure: {
- // C2Component::commit_sm() should return within 5ms.
- setDeadline(now, 250ms, "configure");
- sp<AMessage> format;
- CHECK(msg->findMessage("format", &format));
- configure(format);
- break;
- }
- case kWhatStart: {
- // C2Component::start() should return within 500ms.
- setDeadline(now, 550ms, "start");
- mQueuedWorkCount = 0;
- start();
- break;
- }
- case kWhatStop: {
- // C2Component::stop() should return within 500ms.
- setDeadline(now, 550ms, "stop");
- stop();
-
- mQueuedWorkCount = 0;
- Mutexed<NamedTimePoint>::Locked deadline(mQueueDeadline);
- deadline->set(TimePoint::max(), "none");
- break;
- }
- case kWhatFlush: {
- // C2Component::flush_sm() should return within 5ms.
- setDeadline(now, 50ms, "flush");
- flush();
- break;
- }
- case kWhatCreateInputSurface: {
- // Surface operations may be briefly blocking.
- setDeadline(now, 100ms, "createInputSurface");
- createInputSurface();
- break;
- }
- case kWhatSetInputSurface: {
- // Surface operations may be briefly blocking.
- setDeadline(now, 100ms, "setInputSurface");
- sp<RefBase> obj;
- CHECK(msg->findObject("surface", &obj));
- sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get()));
- setInputSurface(surface);
- break;
- }
- case kWhatWorkDone: {
- std::unique_ptr<C2Work> work;
- size_t numDiscardedInputBuffers;
- bool shouldPost = false;
- {
- Mutexed<std::list<std::unique_ptr<C2Work>>>::Locked queue(mWorkDoneQueue);
- if (queue->empty()) {
- break;
- }
- work.swap(queue->front());
- queue->pop_front();
- shouldPost = !queue->empty();
- }
- {
- Mutexed<std::list<size_t>>::Locked numDiscardedInputBuffersQueue(
- mNumDiscardedInputBuffersQueue);
- if (numDiscardedInputBuffersQueue->empty()) {
- numDiscardedInputBuffers = 0;
- } else {
- numDiscardedInputBuffers = numDiscardedInputBuffersQueue->front();
- numDiscardedInputBuffersQueue->pop_front();
- }
- }
- if (shouldPost) {
- (new AMessage(kWhatWorkDone, this))->post();
- }
-
- if (work->worklets.empty()
- || !(work->worklets.front()->output.flags & C2FrameData::FLAG_INCOMPLETE)) {
- subQueuedWorkCount(1);
- }
- // handle configuration changes in work done
- Mutexed<Config>::Locked config(mConfig);
- bool changed = false;
- Config::Watcher<C2StreamInitDataInfo::output> initData =
- config->watch<C2StreamInitDataInfo::output>();
- if (!work->worklets.empty()
- && (work->worklets.front()->output.flags
- & C2FrameData::FLAG_DISCARD_FRAME) == 0) {
-
- // copy buffer info to config
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- unsigned stream = 0;
- for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
- for (const std::shared_ptr<const C2Info> &info : buf->info()) {
- // move all info into output-stream #0 domain
- updates.emplace_back(C2Param::CopyAsStream(*info, true /* output */, stream));
- }
- for (const C2ConstGraphicBlock &block : buf->data().graphicBlocks()) {
- // ALOGV("got output buffer with crop %u,%u+%u,%u and size %u,%u",
- // block.crop().left, block.crop().top,
- // block.crop().width, block.crop().height,
- // block.width(), block.height());
- updates.emplace_back(new C2StreamCropRectInfo::output(stream, block.crop()));
- updates.emplace_back(new C2StreamPictureSizeInfo::output(
- stream, block.width(), block.height()));
- break; // for now only do the first block
- }
- ++stream;
- }
-
- changed = config->updateConfiguration(updates, config->mOutputDomain);
-
- // copy standard infos to graphic buffers if not already present (otherwise, we
- // may overwrite the actual intermediate value with a final value)
- stream = 0;
- const static std::vector<C2Param::Index> stdGfxInfos = {
- C2StreamRotationInfo::output::PARAM_TYPE,
- C2StreamColorAspectsInfo::output::PARAM_TYPE,
- C2StreamDataSpaceInfo::output::PARAM_TYPE,
- C2StreamHdrStaticInfo::output::PARAM_TYPE,
- C2StreamHdr10PlusInfo::output::PARAM_TYPE,
- C2StreamPixelAspectRatioInfo::output::PARAM_TYPE,
- C2StreamSurfaceScalingInfo::output::PARAM_TYPE
- };
- for (const std::shared_ptr<C2Buffer> &buf : work->worklets.front()->output.buffers) {
- if (buf->data().graphicBlocks().size()) {
- for (C2Param::Index ix : stdGfxInfos) {
- if (!buf->hasInfo(ix)) {
- const C2Param *param =
- config->getConfigParameterValue(ix.withStream(stream));
- if (param) {
- std::shared_ptr<C2Param> info(C2Param::Copy(*param));
- buf->setInfo(std::static_pointer_cast<C2Info>(info));
- }
- }
- }
- }
- ++stream;
- }
- }
- mChannel->onWorkDone(
- std::move(work), changed ? config->mOutputFormat : nullptr,
- initData.hasChanged() ? initData.update().get() : nullptr,
- numDiscardedInputBuffers);
- break;
- }
- case kWhatWatch: {
- // watch message already posted; no-op.
- break;
- }
- default: {
- ALOGE("unrecognized message");
- break;
- }
- }
- setDeadline(TimePoint::max(), 0ms, "none");
-}
-
-void CCodec::setDeadline(
- const TimePoint &now,
- const std::chrono::milliseconds &timeout,
- const char *name) {
- int32_t mult = std::max(1, property_get_int32("debug.stagefright.ccodec_timeout_mult", 1));
- Mutexed<NamedTimePoint>::Locked deadline(mDeadline);
- deadline->set(now + (timeout * mult), name);
-}
-
-void CCodec::initiateReleaseIfStuck() {
- std::string name;
- bool pendingDeadline = false;
- for (Mutexed<NamedTimePoint> *deadlinePtr : { &mDeadline, &mQueueDeadline, &mEosDeadline }) {
- Mutexed<NamedTimePoint>::Locked deadline(*deadlinePtr);
- if (deadline->get() < std::chrono::steady_clock::now()) {
- name = deadline->getName();
- break;
- }
- if (deadline->get() != TimePoint::max()) {
- pendingDeadline = true;
- }
- }
- if (name.empty()) {
- // We're not stuck.
- if (pendingDeadline) {
- // If we are not stuck yet but still has deadline coming up,
- // post watch message to check back later.
- (new AMessage(kWhatWatch, this))->post();
- }
- return;
- }
-
- ALOGW("previous call to %s exceeded timeout", name.c_str());
- initiateRelease(false);
- mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
-}
-
-void CCodec::onWorkQueued(bool eos) {
- ALOGV("queued work count +1 from %d", mQueuedWorkCount.load());
- int32_t count = ++mQueuedWorkCount;
- if (eos) {
- CCodecWatchdog::getInstance()->watch(this);
- Mutexed<NamedTimePoint>::Locked deadline(mEosDeadline);
- deadline->set(std::chrono::steady_clock::now() + 3s, "eos");
- }
- // TODO: query and use input/pipeline/output delay combined
- if (count >= 4) {
- CCodecWatchdog::getInstance()->watch(this);
- Mutexed<NamedTimePoint>::Locked deadline(mQueueDeadline);
- deadline->set(std::chrono::steady_clock::now() + 3s, "queue");
- }
-}
-
-void CCodec::subQueuedWorkCount(uint32_t count) {
- ALOGV("queued work count -%u from %d", count, mQueuedWorkCount.load());
- int32_t currentCount = (mQueuedWorkCount -= count);
- if (currentCount == 0) {
- Mutexed<NamedTimePoint>::Locked deadline(mEosDeadline);
- deadline->set(TimePoint::max(), "none");
- }
- Mutexed<NamedTimePoint>::Locked deadline(mQueueDeadline);
- deadline->set(TimePoint::max(), "none");
-}
-
-} // namespace android
-
-extern "C" android::CodecBase *CreateCodec() {
- return new android::CCodec;
-}
-
-extern "C" android::PersistentSurface *CreateInputSurface() {
- // Attempt to create a Codec2's input surface.
- std::shared_ptr<android::Codec2Client::InputSurface> inputSurface =
- android::Codec2Client::CreateInputSurface();
- if (inputSurface) {
- return new android::PersistentSurface(
- inputSurface->getGraphicBufferProducer(),
- static_cast<android::sp<android::hidl::base::V1_0::IBase>>(
- inputSurface->getHalInterface()));
- }
-
- // Fall back to OMX.
- using namespace android::hardware::media::omx::V1_0;
- using namespace android::hardware::media::omx::V1_0::utils;
- using namespace android::hardware::graphics::bufferqueue::V1_0::utils;
- typedef android::hardware::media::omx::V1_0::Status OmxStatus;
- android::sp<IOmx> omx = IOmx::getService();
- typedef android::hardware::graphics::bufferqueue::V1_0::
- IGraphicBufferProducer HGraphicBufferProducer;
- typedef android::hardware::media::omx::V1_0::
- IGraphicBufferSource HGraphicBufferSource;
- OmxStatus s;
- android::sp<HGraphicBufferProducer> gbp;
- android::sp<HGraphicBufferSource> gbs;
- android::Return<void> transStatus = omx->createInputSurface(
- [&s, &gbp, &gbs](
- OmxStatus status,
- const android::sp<HGraphicBufferProducer>& producer,
- const android::sp<HGraphicBufferSource>& source) {
- s = status;
- gbp = producer;
- gbs = source;
- });
- if (transStatus.isOk() && s == OmxStatus::OK) {
- return new android::PersistentSurface(
- new H2BGraphicBufferProducer(gbp),
- sp<::android::IGraphicBufferSource>(
- new LWGraphicBufferSource(gbs)));
- }
-
- return nullptr;
-}
-
diff --git a/media/sfplugin/CCodec.h b/media/sfplugin/CCodec.h
deleted file mode 100644
index 78b009e..0000000
--- a/media/sfplugin/CCodec.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef C_CODEC_H_
-#define C_CODEC_H_
-
-#include <chrono>
-#include <list>
-#include <memory>
-#include <set>
-
-#include <C2Component.h>
-#include <codec2/hidl/client.h>
-
-#include <android/native_window.h>
-#include <media/hardware/MetadataBufferType.h>
-#include <media/stagefright/foundation/Mutexed.h>
-#include <media/stagefright/CodecBase.h>
-#include <media/stagefright/FrameRenderTracker.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/SkipCutBuffer.h>
-#include <utils/NativeHandle.h>
-#include <hardware/gralloc.h>
-#include <nativebase/nativebase.h>
-
-#include "CCodecConfig.h"
-
-namespace android {
-
-class CCodecBufferChannel;
-class InputSurfaceWrapper;
-struct MediaCodecInfo;
-
-class CCodec : public CodecBase {
-public:
- CCodec();
-
- virtual std::shared_ptr<BufferChannelBase> getBufferChannel() override;
- virtual void initiateAllocateComponent(const sp<AMessage> &msg) override;
- virtual void initiateConfigureComponent(const sp<AMessage> &msg) override;
- virtual void initiateCreateInputSurface() override;
- virtual void initiateSetInputSurface(const sp<PersistentSurface> &surface) override;
- virtual void initiateStart() override;
- virtual void initiateShutdown(bool keepComponentAllocated = false) override;
-
- virtual status_t setSurface(const sp<Surface> &surface) override;
-
- virtual void signalFlush() override;
- virtual void signalResume() override;
-
- virtual void signalSetParameters(const sp<AMessage> &params) override;
- virtual void signalEndOfInputStream() override;
- virtual void signalRequestIDRFrame() override;
-
- void initiateReleaseIfStuck();
- void onWorkDone(std::list<std::unique_ptr<C2Work>> &workItems,
- size_t numDiscardedInputBuffers);
- void onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer);
-
-protected:
- virtual ~CCodec();
-
- virtual void onMessageReceived(const sp<AMessage> &msg) override;
-
-private:
- typedef std::chrono::time_point<std::chrono::steady_clock> TimePoint;
-
- status_t tryAndReportOnError(std::function<status_t()> job);
-
- void initiateStop();
- void initiateRelease(bool sendCallback = true);
-
- void allocate(const sp<MediaCodecInfo> &codecInfo);
- void configure(const sp<AMessage> &msg);
- void start();
- void stop();
- void flush();
- void release(bool sendCallback);
-
- void createInputSurface();
- void setInputSurface(const sp<PersistentSurface> &surface);
- status_t setupInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
- void setParameters(const sp<AMessage> &params);
-
- void setDeadline(
- const TimePoint &now,
- const std::chrono::milliseconds &timeout,
- const char *name);
-
- void onWorkQueued(bool eos);
- void subQueuedWorkCount(uint32_t count);
-
- enum {
- kWhatAllocate,
- kWhatConfigure,
- kWhatStart,
- kWhatFlush,
- kWhatStop,
- kWhatRelease,
- kWhatCreateInputSurface,
- kWhatSetInputSurface,
- kWhatSetParameters,
-
- kWhatWorkDone,
- kWhatWatch,
- };
-
- enum {
- RELEASED,
- ALLOCATED,
- FLUSHED,
- RUNNING,
-
- ALLOCATING, // RELEASED -> ALLOCATED
- STARTING, // ALLOCATED -> RUNNING
- STOPPING, // RUNNING -> ALLOCATED
- FLUSHING, // RUNNING -> FLUSHED
- RESUMING, // FLUSHED -> RUNNING
- RELEASING, // {ANY EXCEPT RELEASED} -> RELEASED
- };
-
- struct State {
- inline State() : mState(RELEASED) {}
- inline int get() const { return mState; }
- inline void set(int newState) { mState = newState; }
-
- std::shared_ptr<Codec2Client::Component> comp;
- private:
- int mState;
- };
-
- struct NamedTimePoint {
- NamedTimePoint() : mTimePoint(TimePoint::max()), mName("") {}
-
- inline void set(
- const TimePoint &timePoint,
- const char *name) {
- mTimePoint = timePoint;
- mName = name;
- }
-
- inline TimePoint get() const { return mTimePoint; }
- inline const char *getName() const { return mName; }
- private:
- TimePoint mTimePoint;
- const char *mName;
- };
-
- Mutexed<State> mState;
- std::shared_ptr<CCodecBufferChannel> mChannel;
-
- std::shared_ptr<Codec2Client> mClient;
- std::shared_ptr<Codec2Client::Listener> mClientListener;
- struct ClientListener;
-
- Mutexed<NamedTimePoint> mDeadline;
- std::atomic_int32_t mQueuedWorkCount;
- Mutexed<NamedTimePoint> mQueueDeadline;
- Mutexed<NamedTimePoint> mEosDeadline;
- typedef CCodecConfig Config;
- Mutexed<Config> mConfig;
- Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue;
- Mutexed<std::list<size_t>> mNumDiscardedInputBuffersQueue;
-
- friend class CCodecCallbackImpl;
-
- DISALLOW_EVIL_CONSTRUCTORS(CCodec);
-};
-
-} // namespace android
-
-#endif // C_CODEC_H_
diff --git a/media/sfplugin/CCodecBufferChannel.cpp b/media/sfplugin/CCodecBufferChannel.cpp
deleted file mode 100644
index d4b08c1..0000000
--- a/media/sfplugin/CCodecBufferChannel.cpp
+++ /dev/null
@@ -1,2862 +0,0 @@
-/*
- * Copyright 2017, 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 "CCodecBufferChannel"
-#include <utils/Log.h>
-
-#include <numeric>
-
-#include <C2AllocatorGralloc.h>
-#include <C2PlatformSupport.h>
-#include <C2BlockInternal.h>
-#include <C2Config.h>
-#include <C2Debug.h>
-
-#include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <android-base/stringprintf.h>
-#include <binder/MemoryDealer.h>
-#include <gui/Surface.h>
-#include <media/openmax/OMX_Core.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ALookup.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaCodec.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/MediaCodecBuffer.h>
-#include <system/window.h>
-
-#include "CCodecBufferChannel.h"
-#include "Codec2Buffer.h"
-#include "SkipCutBuffer.h"
-
-namespace android {
-
-using android::base::StringPrintf;
-using hardware::hidl_handle;
-using hardware::hidl_string;
-using hardware::hidl_vec;
-using namespace hardware::cas::V1_0;
-using namespace hardware::cas::native::V1_0;
-
-using CasStatus = hardware::cas::V1_0::Status;
-
-/**
- * Base class for representation of buffers at one port.
- */
-class CCodecBufferChannel::Buffers {
-public:
- Buffers(const char *componentName, const char *name = "Buffers")
- : mComponentName(componentName),
- mChannelName(std::string(componentName) + ":" + name),
- mName(mChannelName.c_str()) {
- }
- virtual ~Buffers() = default;
-
- /**
- * Set format for MediaCodec-facing buffers.
- */
- void setFormat(const sp<AMessage> &format) {
- CHECK(format != nullptr);
- mFormat = format;
- }
-
- /**
- * Return a copy of current format.
- */
- sp<AMessage> dupFormat() {
- return mFormat != nullptr ? mFormat->dup() : nullptr;
- }
-
- /**
- * Returns true if the buffers are operating under array mode.
- */
- virtual bool isArrayMode() const { return false; }
-
- /**
- * Fills the vector with MediaCodecBuffer's if in array mode; otherwise,
- * no-op.
- */
- virtual void getArray(Vector<sp<MediaCodecBuffer>> *) const {}
-
-protected:
- std::string mComponentName; ///< name of component for debugging
- std::string mChannelName; ///< name of channel for debugging
- const char *mName; ///< C-string version of channel name
- // Format to be used for creating MediaCodec-facing buffers.
- sp<AMessage> mFormat;
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(Buffers);
-};
-
-class CCodecBufferChannel::InputBuffers : public CCodecBufferChannel::Buffers {
-public:
- InputBuffers(const char *componentName, const char *name = "Input[]")
- : Buffers(componentName, name) { }
- virtual ~InputBuffers() = default;
-
- /**
- * Set a block pool to obtain input memory blocks.
- */
- void setPool(const std::shared_ptr<C2BlockPool> &pool) { mPool = pool; }
-
- /**
- * Get a new MediaCodecBuffer for input and its corresponding index.
- * Returns false if no new buffer can be obtained at the moment.
- */
- virtual bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) = 0;
-
- /**
- * Release the buffer obtained from requestNewBuffer() and get the
- * associated C2Buffer object back. Returns true if the buffer was on file
- * and released successfully.
- */
- virtual bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) = 0;
-
- /**
- * Release the buffer that is no longer used by the codec process. Return
- * true if and only if the buffer was on file and released successfully.
- */
- virtual bool expireComponentBuffer(
- const std::shared_ptr<C2Buffer> &c2buffer) = 0;
-
- /**
- * Flush internal state. After this call, no index or buffer previously
- * returned from requestNewBuffer() is valid.
- */
- virtual void flush() = 0;
-
- /**
- * Return array-backed version of input buffers. The returned object
- * shall retain the internal state so that it will honor index and
- * buffer from previous calls of requestNewBuffer().
- */
- virtual std::unique_ptr<InputBuffers> toArrayMode(size_t size) = 0;
-
-protected:
- // Pool to obtain blocks for input buffers.
- std::shared_ptr<C2BlockPool> mPool;
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(InputBuffers);
-};
-
-class CCodecBufferChannel::OutputBuffers : public CCodecBufferChannel::Buffers {
-public:
- OutputBuffers(const char *componentName, const char *name = "Output")
- : Buffers(componentName, name) { }
- virtual ~OutputBuffers() = default;
-
- /**
- * Register output C2Buffer from the component and obtain corresponding
- * index and MediaCodecBuffer object. Returns false if registration
- * fails.
- */
- virtual status_t registerBuffer(
- const std::shared_ptr<C2Buffer> &buffer,
- size_t *index,
- sp<MediaCodecBuffer> *clientBuffer) = 0;
-
- /**
- * Register codec specific data as a buffer to be consistent with
- * MediaCodec behavior.
- */
- virtual status_t registerCsd(
- const C2StreamCsdInfo::output * /* csd */,
- size_t * /* index */,
- sp<MediaCodecBuffer> * /* clientBuffer */) = 0;
-
- /**
- * Release the buffer obtained from registerBuffer() and get the
- * associated C2Buffer object back. Returns true if the buffer was on file
- * and released successfully.
- */
- virtual bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) = 0;
-
- /**
- * Flush internal state. After this call, no index or buffer previously
- * returned from registerBuffer() is valid.
- */
- virtual void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) = 0;
-
- /**
- * Return array-backed version of output buffers. The returned object
- * shall retain the internal state so that it will honor index and
- * buffer from previous calls of registerBuffer().
- */
- virtual std::unique_ptr<OutputBuffers> toArrayMode(size_t size) = 0;
-
- /**
- * Initialize SkipCutBuffer object.
- */
- void initSkipCutBuffer(
- int32_t delay, int32_t padding, int32_t sampleRate, int32_t channelCount) {
- CHECK(mSkipCutBuffer == nullptr);
- mDelay = delay;
- mPadding = padding;
- mSampleRate = sampleRate;
- setSkipCutBuffer(delay, padding, channelCount);
- }
-
- /**
- * Update the SkipCutBuffer object. No-op if it's never initialized.
- */
- void updateSkipCutBuffer(int32_t sampleRate, int32_t channelCount) {
- if (mSkipCutBuffer == nullptr) {
- return;
- }
- int32_t delay = mDelay;
- int32_t padding = mPadding;
- if (sampleRate != mSampleRate) {
- delay = ((int64_t)delay * sampleRate) / mSampleRate;
- padding = ((int64_t)padding * sampleRate) / mSampleRate;
- }
- setSkipCutBuffer(delay, padding, channelCount);
- }
-
- /**
- * Submit buffer to SkipCutBuffer object, if initialized.
- */
- void submit(const sp<MediaCodecBuffer> &buffer) {
- if (mSkipCutBuffer != nullptr) {
- mSkipCutBuffer->submit(buffer);
- }
- }
-
- /**
- * Transfer SkipCutBuffer object to the other Buffers object.
- */
- void transferSkipCutBuffer(const sp<SkipCutBuffer> &scb) {
- mSkipCutBuffer = scb;
- }
-
-protected:
- sp<SkipCutBuffer> mSkipCutBuffer;
-
-private:
- int32_t mDelay;
- int32_t mPadding;
- int32_t mSampleRate;
-
- void setSkipCutBuffer(int32_t skip, int32_t cut, int32_t channelCount) {
- if (mSkipCutBuffer != nullptr) {
- size_t prevSize = mSkipCutBuffer->size();
- if (prevSize != 0u) {
- ALOGD("[%s] Replacing SkipCutBuffer holding %zu bytes", mName, prevSize);
- }
- }
- mSkipCutBuffer = new SkipCutBuffer(skip, cut, channelCount);
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(OutputBuffers);
-};
-
-namespace {
-
-// TODO: get this info from component
-const static size_t kMinInputBufferArraySize = 4;
-const static size_t kMaxPipelineCapacity = 18;
-const static size_t kChannelOutputDelay = 0;
-const static size_t kMinOutputBufferArraySize = kMaxPipelineCapacity +
- kChannelOutputDelay;
-const static size_t kLinearBufferSize = 1048576;
-// This can fit 4K RGBA frame, and most likely client won't need more than this.
-const static size_t kMaxLinearBufferSize = 3840 * 2160 * 4;
-
-/**
- * Simple local buffer pool backed by std::vector.
- */
-class LocalBufferPool : public std::enable_shared_from_this<LocalBufferPool> {
-public:
- /**
- * Create a new LocalBufferPool object.
- *
- * \param poolCapacity max total size of buffers managed by this pool.
- *
- * \return a newly created pool object.
- */
- static std::shared_ptr<LocalBufferPool> Create(size_t poolCapacity) {
- return std::shared_ptr<LocalBufferPool>(new LocalBufferPool(poolCapacity));
- }
-
- /**
- * Return an ABuffer object whose size is at least |capacity|.
- *
- * \param capacity requested capacity
- * \return nullptr if the pool capacity is reached
- * an ABuffer object otherwise.
- */
- sp<ABuffer> newBuffer(size_t capacity) {
- Mutex::Autolock lock(mMutex);
- auto it = std::find_if(
- mPool.begin(), mPool.end(),
- [capacity](const std::vector<uint8_t> &vec) {
- return vec.capacity() >= capacity;
- });
- if (it != mPool.end()) {
- sp<ABuffer> buffer = new VectorBuffer(std::move(*it), shared_from_this());
- mPool.erase(it);
- return buffer;
- }
- if (mUsedSize + capacity > mPoolCapacity) {
- while (!mPool.empty()) {
- mUsedSize -= mPool.back().capacity();
- mPool.pop_back();
- }
- if (mUsedSize + capacity > mPoolCapacity) {
- ALOGD("mUsedSize = %zu, capacity = %zu, mPoolCapacity = %zu",
- mUsedSize, capacity, mPoolCapacity);
- return nullptr;
- }
- }
- std::vector<uint8_t> vec(capacity);
- mUsedSize += vec.capacity();
- return new VectorBuffer(std::move(vec), shared_from_this());
- }
-
-private:
- /**
- * ABuffer backed by std::vector.
- */
- class VectorBuffer : public ::android::ABuffer {
- public:
- /**
- * Construct a VectorBuffer by taking the ownership of supplied vector.
- *
- * \param vec backing vector of the buffer. this object takes
- * ownership at construction.
- * \param pool a LocalBufferPool object to return the vector at
- * destruction.
- */
- VectorBuffer(std::vector<uint8_t> &&vec, const std::shared_ptr<LocalBufferPool> &pool)
- : ABuffer(vec.data(), vec.capacity()),
- mVec(std::move(vec)),
- mPool(pool) {
- }
-
- ~VectorBuffer() override {
- std::shared_ptr<LocalBufferPool> pool = mPool.lock();
- if (pool) {
- // If pool is alive, return the vector back to the pool so that
- // it can be recycled.
- pool->returnVector(std::move(mVec));
- }
- }
-
- private:
- std::vector<uint8_t> mVec;
- std::weak_ptr<LocalBufferPool> mPool;
- };
-
- Mutex mMutex;
- size_t mPoolCapacity;
- size_t mUsedSize;
- std::list<std::vector<uint8_t>> mPool;
-
- /**
- * Private constructor to prevent constructing non-managed LocalBufferPool.
- */
- explicit LocalBufferPool(size_t poolCapacity)
- : mPoolCapacity(poolCapacity), mUsedSize(0) {
- }
-
- /**
- * Take back the ownership of vec from the destructed VectorBuffer and put
- * it in front of the pool.
- */
- void returnVector(std::vector<uint8_t> &&vec) {
- Mutex::Autolock lock(mMutex);
- mPool.push_front(std::move(vec));
- }
-
- DISALLOW_EVIL_CONSTRUCTORS(LocalBufferPool);
-};
-
-sp<GraphicBlockBuffer> AllocateGraphicBuffer(
- const std::shared_ptr<C2BlockPool> &pool,
- const sp<AMessage> &format,
- uint32_t pixelFormat,
- const C2MemoryUsage &usage,
- const std::shared_ptr<LocalBufferPool> &localBufferPool) {
- int32_t width, height;
- if (!format->findInt32("width", &width) || !format->findInt32("height", &height)) {
- ALOGD("format lacks width or height");
- return nullptr;
- }
-
- std::shared_ptr<C2GraphicBlock> block;
- c2_status_t err = pool->fetchGraphicBlock(
- width, height, pixelFormat, usage, &block);
- if (err != C2_OK) {
- ALOGD("fetch graphic block failed: %d", err);
- return nullptr;
- }
-
- return GraphicBlockBuffer::Allocate(
- format,
- block,
- [localBufferPool](size_t capacity) {
- return localBufferPool->newBuffer(capacity);
- });
-}
-
-class BuffersArrayImpl;
-
-/**
- * Flexible buffer slots implementation.
- */
-class FlexBuffersImpl {
-public:
- FlexBuffersImpl(const char *name)
- : mImplName(std::string(name) + ".Impl"),
- mName(mImplName.c_str()) { }
-
- /**
- * Assign an empty slot for a buffer and return the index. If there's no
- * empty slot, just add one at the end and return it.
- *
- * \param buffer[in] a new buffer to assign a slot.
- * \return index of the assigned slot.
- */
- size_t assignSlot(const sp<Codec2Buffer> &buffer) {
- for (size_t i = 0; i < mBuffers.size(); ++i) {
- if (mBuffers[i].clientBuffer == nullptr
- && mBuffers[i].compBuffer.expired()) {
- mBuffers[i].clientBuffer = buffer;
- return i;
- }
- }
- mBuffers.push_back({ buffer, std::weak_ptr<C2Buffer>() });
- return mBuffers.size() - 1;
- }
-
- /**
- * Release the slot from the client, and get the C2Buffer object back from
- * the previously assigned buffer. Note that the slot is not completely free
- * until the returned C2Buffer object is freed.
- *
- * \param buffer[in] the buffer previously assigned a slot.
- * \param c2buffer[in,out] pointer to C2Buffer to be populated. Ignored
- * if null.
- * \return true if the buffer is successfully released from a slot
- * false otherwise
- */
- bool releaseSlot(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) {
- sp<Codec2Buffer> clientBuffer;
- size_t index = mBuffers.size();
- for (size_t i = 0; i < mBuffers.size(); ++i) {
- if (mBuffers[i].clientBuffer == buffer) {
- clientBuffer = mBuffers[i].clientBuffer;
- if (release) {
- mBuffers[i].clientBuffer.clear();
- }
- index = i;
- break;
- }
- }
- if (clientBuffer == nullptr) {
- ALOGV("[%s] %s: No matching buffer found", mName, __func__);
- return false;
- }
- std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
- if (!result) {
- result = clientBuffer->asC2Buffer();
- mBuffers[index].compBuffer = result;
- }
- if (c2buffer) {
- *c2buffer = result;
- }
- return true;
- }
-
- bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
- for (size_t i = 0; i < mBuffers.size(); ++i) {
- std::shared_ptr<C2Buffer> compBuffer =
- mBuffers[i].compBuffer.lock();
- if (!compBuffer || compBuffer != c2buffer) {
- continue;
- }
- mBuffers[i].compBuffer.reset();
- ALOGV("[%s] codec released buffer #%zu", mName, i);
- return true;
- }
- ALOGV("[%s] codec released an unknown buffer", mName);
- return false;
- }
-
- void flush() {
- ALOGV("[%s] buffers are flushed %zu", mName, mBuffers.size());
- mBuffers.clear();
- }
-
-private:
- friend class BuffersArrayImpl;
-
- std::string mImplName; ///< name for debugging
- const char *mName; ///< C-string version of name
-
- struct Entry {
- sp<Codec2Buffer> clientBuffer;
- std::weak_ptr<C2Buffer> compBuffer;
- };
- std::vector<Entry> mBuffers;
-};
-
-/**
- * Static buffer slots implementation based on a fixed-size array.
- */
-class BuffersArrayImpl {
-public:
- BuffersArrayImpl()
- : mImplName("BuffersArrayImpl"),
- mName(mImplName.c_str()) { }
-
- /**
- * Initialize buffer array from the original |impl|. The buffers known by
- * the client is preserved, and the empty slots are populated so that the
- * array size is at least |minSize|.
- *
- * \param impl[in] FlexBuffersImpl object used so far.
- * \param minSize[in] minimum size of the buffer array.
- * \param allocate[in] function to allocate a client buffer for an empty slot.
- */
- void initialize(
- const FlexBuffersImpl &impl,
- size_t minSize,
- std::function<sp<Codec2Buffer>()> allocate) {
- mImplName = impl.mImplName + "[N]";
- mName = mImplName.c_str();
- for (size_t i = 0; i < impl.mBuffers.size(); ++i) {
- sp<Codec2Buffer> clientBuffer = impl.mBuffers[i].clientBuffer;
- bool ownedByClient = (clientBuffer != nullptr);
- if (!ownedByClient) {
- clientBuffer = allocate();
- }
- mBuffers.push_back({ clientBuffer, impl.mBuffers[i].compBuffer, ownedByClient });
- }
- ALOGV("[%s] converted %zu buffers to array mode of %zu", mName, mBuffers.size(), minSize);
- for (size_t i = impl.mBuffers.size(); i < minSize; ++i) {
- mBuffers.push_back({ allocate(), std::weak_ptr<C2Buffer>(), false });
- }
- }
-
- /**
- * Grab a buffer from the underlying array which matches the criteria.
- *
- * \param index[out] index of the slot.
- * \param buffer[out] the matching buffer.
- * \param match[in] a function to test whether the buffer matches the
- * criteria or not.
- * \return OK if successful,
- * WOULD_BLOCK if slots are being used,
- * NO_MEMORY if no slot matches the criteria, even though it's
- * available
- */
- status_t grabBuffer(
- size_t *index,
- sp<Codec2Buffer> *buffer,
- std::function<bool(const sp<Codec2Buffer> &)> match =
- [](const sp<Codec2Buffer> &) { return true; }) {
- // allBuffersDontMatch remains true if all buffers are available but
- // match() returns false for every buffer.
- bool allBuffersDontMatch = true;
- for (size_t i = 0; i < mBuffers.size(); ++i) {
- if (!mBuffers[i].ownedByClient && mBuffers[i].compBuffer.expired()) {
- if (match(mBuffers[i].clientBuffer)) {
- mBuffers[i].ownedByClient = true;
- *buffer = mBuffers[i].clientBuffer;
- (*buffer)->meta()->clear();
- (*buffer)->setRange(0, (*buffer)->capacity());
- *index = i;
- return OK;
- }
- } else {
- allBuffersDontMatch = false;
- }
- }
- return allBuffersDontMatch ? NO_MEMORY : WOULD_BLOCK;
- }
-
- /**
- * Return the buffer from the client, and get the C2Buffer object back from
- * the buffer. Note that the slot is not completely free until the returned
- * C2Buffer object is freed.
- *
- * \param buffer[in] the buffer previously grabbed.
- * \param c2buffer[in,out] pointer to C2Buffer to be populated. Ignored
- * if null.
- * \return true if the buffer is successfully returned
- * false otherwise
- */
- bool returnBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) {
- sp<Codec2Buffer> clientBuffer;
- size_t index = mBuffers.size();
- for (size_t i = 0; i < mBuffers.size(); ++i) {
- if (mBuffers[i].clientBuffer == buffer) {
- if (!mBuffers[i].ownedByClient) {
- ALOGD("[%s] Client returned a buffer it does not own according to our record: %zu", mName, i);
- }
- clientBuffer = mBuffers[i].clientBuffer;
- if (release) {
- mBuffers[i].ownedByClient = false;
- }
- index = i;
- break;
- }
- }
- if (clientBuffer == nullptr) {
- ALOGV("[%s] %s: No matching buffer found", mName, __func__);
- return false;
- }
- ALOGV("[%s] %s: matching buffer found (index=%zu)", mName, __func__, index);
- std::shared_ptr<C2Buffer> result = mBuffers[index].compBuffer.lock();
- if (!result) {
- result = clientBuffer->asC2Buffer();
- mBuffers[index].compBuffer = result;
- }
- if (c2buffer) {
- *c2buffer = result;
- }
- return true;
- }
-
- bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &c2buffer) {
- for (size_t i = 0; i < mBuffers.size(); ++i) {
- std::shared_ptr<C2Buffer> compBuffer =
- mBuffers[i].compBuffer.lock();
- if (!compBuffer) {
- continue;
- }
- if (c2buffer == compBuffer) {
- if (mBuffers[i].ownedByClient) {
- // This should not happen.
- ALOGD("[%s] codec released a buffer owned by client "
- "(index %zu)", mName, i);
- }
- mBuffers[i].compBuffer.reset();
- ALOGV("[%s] codec released buffer #%zu(array mode)", mName, i);
- return true;
- }
- }
- ALOGV("[%s] codec released an unknown buffer (array mode)", mName);
- return false;
- }
-
- /**
- * Populate |array| with the underlying buffer array.
- *
- * \param array[out] an array to be filled with the underlying buffer array.
- */
- void getArray(Vector<sp<MediaCodecBuffer>> *array) const {
- array->clear();
- for (const Entry &entry : mBuffers) {
- array->push(entry.clientBuffer);
- }
- }
-
- /**
- * The client abandoned all known buffers, so reclaim the ownership.
- */
- void flush() {
- for (Entry &entry : mBuffers) {
- entry.ownedByClient = false;
- }
- }
-
- void realloc(std::function<sp<Codec2Buffer>()> alloc) {
- size_t size = mBuffers.size();
- mBuffers.clear();
- for (size_t i = 0; i < size; ++i) {
- mBuffers.push_back({ alloc(), std::weak_ptr<C2Buffer>(), false });
- }
- }
-
-private:
- std::string mImplName; ///< name for debugging
- const char *mName; ///< C-string version of name
-
- struct Entry {
- const sp<Codec2Buffer> clientBuffer;
- std::weak_ptr<C2Buffer> compBuffer;
- bool ownedByClient;
- };
- std::vector<Entry> mBuffers;
-};
-
-class InputBuffersArray : public CCodecBufferChannel::InputBuffers {
-public:
- InputBuffersArray(const char *componentName, const char *name = "Input[N]")
- : InputBuffers(componentName, name) { }
- ~InputBuffersArray() override = default;
-
- void initialize(
- const FlexBuffersImpl &impl,
- size_t minSize,
- std::function<sp<Codec2Buffer>()> allocate) {
- mImpl.initialize(impl, minSize, allocate);
- }
-
- bool isArrayMode() const final { return true; }
-
- std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
- size_t) final {
- return nullptr;
- }
-
- void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
- mImpl.getArray(array);
- }
-
- bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
- sp<Codec2Buffer> c2Buffer;
- status_t err = mImpl.grabBuffer(index, &c2Buffer);
- if (err == OK) {
- c2Buffer->setFormat(mFormat);
- *buffer = c2Buffer;
- return true;
- }
- return false;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) override {
- return mImpl.returnBuffer(buffer, c2buffer, release);
- }
-
- bool expireComponentBuffer(
- const std::shared_ptr<C2Buffer> &c2buffer) override {
- return mImpl.expireComponentBuffer(c2buffer);
- }
-
- void flush() override {
- mImpl.flush();
- }
-
-private:
- BuffersArrayImpl mImpl;
-};
-
-class LinearInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
- LinearInputBuffers(const char *componentName, const char *name = "1D-Input")
- : InputBuffers(componentName, name),
- mImpl(mName) { }
-
- bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
- int32_t capacity = kLinearBufferSize;
- (void)mFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
- if ((size_t)capacity > kMaxLinearBufferSize) {
- ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
- capacity = kMaxLinearBufferSize;
- }
- // TODO: proper max input size
- // TODO: read usage from intf
- sp<Codec2Buffer> newBuffer = alloc((size_t)capacity);
- if (newBuffer == nullptr) {
- return false;
- }
- *index = mImpl.assignSlot(newBuffer);
- *buffer = newBuffer;
- return true;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) override {
- return mImpl.releaseSlot(buffer, c2buffer, release);
- }
-
- bool expireComponentBuffer(
- const std::shared_ptr<C2Buffer> &c2buffer) override {
- return mImpl.expireComponentBuffer(c2buffer);
- }
-
- void flush() override {
- // This is no-op by default unless we're in array mode where we need to keep
- // track of the flushed work.
- mImpl.flush();
- }
-
- std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
- size_t size) final {
- int32_t capacity = kLinearBufferSize;
- (void)mFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
- if ((size_t)capacity > kMaxLinearBufferSize) {
- ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
- capacity = kMaxLinearBufferSize;
- }
- // TODO: proper max input size
- // TODO: read usage from intf
- std::unique_ptr<InputBuffersArray> array(
- new InputBuffersArray(mComponentName.c_str(), "1D-Input[N]"));
- array->setPool(mPool);
- array->setFormat(mFormat);
- array->initialize(
- mImpl,
- size,
- [this, capacity] () -> sp<Codec2Buffer> { return alloc(capacity); });
- return std::move(array);
- }
-
- virtual sp<Codec2Buffer> alloc(size_t size) {
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- std::shared_ptr<C2LinearBlock> block;
-
- c2_status_t err = mPool->fetchLinearBlock(size, usage, &block);
- if (err != C2_OK) {
- return nullptr;
- }
-
- return LinearBlockBuffer::Allocate(mFormat, block);
- }
-
-private:
- FlexBuffersImpl mImpl;
-};
-
-class EncryptedLinearInputBuffers : public LinearInputBuffers {
-public:
- EncryptedLinearInputBuffers(
- bool secure,
- const sp<MemoryDealer> &dealer,
- const sp<ICrypto> &crypto,
- int32_t heapSeqNum,
- size_t capacity,
- const char *componentName, const char *name = "EncryptedInput")
- : LinearInputBuffers(componentName, name),
- mUsage({0, 0}),
- mDealer(dealer),
- mCrypto(crypto),
- mHeapSeqNum(heapSeqNum) {
- if (secure) {
- mUsage = { C2MemoryUsage::READ_PROTECTED, 0 };
- } else {
- mUsage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- }
- for (size_t i = 0; i < kMinInputBufferArraySize; ++i) {
- sp<IMemory> memory = mDealer->allocate(capacity);
- if (memory == nullptr) {
- ALOGD("[%s] Failed to allocate memory from dealer: only %zu slots allocated", mName, i);
- break;
- }
- mMemoryVector.push_back({std::weak_ptr<C2LinearBlock>(), memory});
- }
- }
-
- ~EncryptedLinearInputBuffers() override {
- }
-
- sp<Codec2Buffer> alloc(size_t size) override {
- sp<IMemory> memory;
- size_t slot = 0;
- for (; slot < mMemoryVector.size(); ++slot) {
- if (mMemoryVector[slot].block.expired()) {
- memory = mMemoryVector[slot].memory;
- break;
- }
- }
- if (memory == nullptr) {
- return nullptr;
- }
-
- std::shared_ptr<C2LinearBlock> block;
- c2_status_t err = mPool->fetchLinearBlock(size, mUsage, &block);
- if (err != C2_OK || block == nullptr) {
- return nullptr;
- }
-
- mMemoryVector[slot].block = block;
- return new EncryptedLinearBlockBuffer(mFormat, block, memory, mHeapSeqNum);
- }
-
-private:
- C2MemoryUsage mUsage;
- sp<MemoryDealer> mDealer;
- sp<ICrypto> mCrypto;
- int32_t mHeapSeqNum;
- struct Entry {
- std::weak_ptr<C2LinearBlock> block;
- sp<IMemory> memory;
- };
- std::vector<Entry> mMemoryVector;
-};
-
-class GraphicMetadataInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
- GraphicMetadataInputBuffers(const char *componentName, const char *name = "2D-MetaInput")
- : InputBuffers(componentName, name),
- mImpl(mName),
- mStore(GetCodec2PlatformAllocatorStore()) { }
- ~GraphicMetadataInputBuffers() override = default;
-
- bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
- std::shared_ptr<C2Allocator> alloc;
- c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
- if (err != C2_OK) {
- return false;
- }
- sp<GraphicMetadataBuffer> newBuffer = new GraphicMetadataBuffer(mFormat, alloc);
- if (newBuffer == nullptr) {
- return false;
- }
- *index = mImpl.assignSlot(newBuffer);
- *buffer = newBuffer;
- return true;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) override {
- return mImpl.releaseSlot(buffer, c2buffer, release);
- }
-
- bool expireComponentBuffer(
- const std::shared_ptr<C2Buffer> &c2buffer) override {
- return mImpl.expireComponentBuffer(c2buffer);
- }
-
- void flush() override {
- // This is no-op by default unless we're in array mode where we need to keep
- // track of the flushed work.
- }
-
- std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
- size_t size) final {
- std::shared_ptr<C2Allocator> alloc;
- c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc);
- if (err != C2_OK) {
- return nullptr;
- }
- std::unique_ptr<InputBuffersArray> array(
- new InputBuffersArray(mComponentName.c_str(), "2D-MetaInput[N]"));
- array->setPool(mPool);
- array->setFormat(mFormat);
- array->initialize(
- mImpl,
- size,
- [format = mFormat, alloc]() -> sp<Codec2Buffer> {
- return new GraphicMetadataBuffer(format, alloc);
- });
- return std::move(array);
- }
-
-private:
- FlexBuffersImpl mImpl;
- std::shared_ptr<C2AllocatorStore> mStore;
-};
-
-class GraphicInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
- GraphicInputBuffers(const char *componentName, const char *name = "2D-BB-Input")
- : InputBuffers(componentName, name),
- mImpl(mName),
- mLocalBufferPool(LocalBufferPool::Create(
- kMaxLinearBufferSize * kMinInputBufferArraySize)) { }
- ~GraphicInputBuffers() override = default;
-
- bool requestNewBuffer(size_t *index, sp<MediaCodecBuffer> *buffer) override {
- // TODO: proper max input size
- // TODO: read usage from intf
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- sp<GraphicBlockBuffer> newBuffer = AllocateGraphicBuffer(
- mPool, mFormat, HAL_PIXEL_FORMAT_YV12, usage, mLocalBufferPool);
- if (newBuffer == nullptr) {
- return false;
- }
- *index = mImpl.assignSlot(newBuffer);
- *buffer = newBuffer;
- return true;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer,
- bool release) override {
- return mImpl.releaseSlot(buffer, c2buffer, release);
- }
-
- bool expireComponentBuffer(
- const std::shared_ptr<C2Buffer> &c2buffer) override {
- return mImpl.expireComponentBuffer(c2buffer);
- }
- void flush() override {
- // This is no-op by default unless we're in array mode where we need to keep
- // track of the flushed work.
- }
-
- std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
- size_t size) final {
- std::unique_ptr<InputBuffersArray> array(
- new InputBuffersArray(mComponentName.c_str(), "2D-BB-Input[N]"));
- array->setPool(mPool);
- array->setFormat(mFormat);
- array->initialize(
- mImpl,
- size,
- [pool = mPool, format = mFormat, lbp = mLocalBufferPool]() -> sp<Codec2Buffer> {
- C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
- return AllocateGraphicBuffer(
- pool, format, HAL_PIXEL_FORMAT_YV12, usage, lbp);
- });
- return std::move(array);
- }
-
-private:
- FlexBuffersImpl mImpl;
- std::shared_ptr<LocalBufferPool> mLocalBufferPool;
-};
-
-class DummyInputBuffers : public CCodecBufferChannel::InputBuffers {
-public:
- DummyInputBuffers(const char *componentName, const char *name = "2D-Input")
- : InputBuffers(componentName, name) { }
-
- bool requestNewBuffer(size_t *, sp<MediaCodecBuffer> *) override {
- return false;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &, std::shared_ptr<C2Buffer> *, bool) override {
- return false;
- }
-
- bool expireComponentBuffer(const std::shared_ptr<C2Buffer> &) override {
- return false;
- }
-
- void flush() override {
- }
-
- std::unique_ptr<CCodecBufferChannel::InputBuffers> toArrayMode(
- size_t) final {
- return nullptr;
- }
-
- bool isArrayMode() const final { return true; }
-
- void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
- array->clear();
- }
-};
-
-class OutputBuffersArray : public CCodecBufferChannel::OutputBuffers {
-public:
- OutputBuffersArray(const char *componentName, const char *name = "Output[N]")
- : OutputBuffers(componentName, name) { }
- ~OutputBuffersArray() override = default;
-
- void initialize(
- const FlexBuffersImpl &impl,
- size_t minSize,
- std::function<sp<Codec2Buffer>()> allocate) {
- mImpl.initialize(impl, minSize, allocate);
- }
-
- bool isArrayMode() const final { return true; }
-
- std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode(
- size_t) final {
- return nullptr;
- }
-
- status_t registerBuffer(
- const std::shared_ptr<C2Buffer> &buffer,
- size_t *index,
- sp<MediaCodecBuffer> *clientBuffer) final {
- sp<Codec2Buffer> c2Buffer;
- status_t err = mImpl.grabBuffer(
- index,
- &c2Buffer,
- [buffer](const sp<Codec2Buffer> &clientBuffer) {
- return clientBuffer->canCopy(buffer);
- });
- if (err == WOULD_BLOCK) {
- ALOGV("[%s] buffers temporarily not available", mName);
- return err;
- } else if (err != OK) {
- ALOGD("[%s] grabBuffer failed: %d", mName, err);
- return err;
- }
- c2Buffer->setFormat(mFormat);
- if (!c2Buffer->copy(buffer)) {
- ALOGD("[%s] copy buffer failed", mName);
- return WOULD_BLOCK;
- }
- submit(c2Buffer);
- *clientBuffer = c2Buffer;
- ALOGV("[%s] grabbed buffer %zu", mName, *index);
- return OK;
- }
-
- status_t registerCsd(
- const C2StreamCsdInfo::output *csd,
- size_t *index,
- sp<MediaCodecBuffer> *clientBuffer) final {
- sp<Codec2Buffer> c2Buffer;
- status_t err = mImpl.grabBuffer(
- index,
- &c2Buffer,
- [csd](const sp<Codec2Buffer> &clientBuffer) {
- return clientBuffer->base() != nullptr
- && clientBuffer->capacity() >= csd->flexCount();
- });
- if (err != OK) {
- return err;
- }
- memcpy(c2Buffer->base(), csd->m.value, csd->flexCount());
- c2Buffer->setRange(0, csd->flexCount());
- c2Buffer->setFormat(mFormat);
- *clientBuffer = c2Buffer;
- return OK;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer, std::shared_ptr<C2Buffer> *c2buffer) override {
- return mImpl.returnBuffer(buffer, c2buffer, true);
- }
-
- void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
- (void)flushedWork;
- mImpl.flush();
- if (mSkipCutBuffer != nullptr) {
- mSkipCutBuffer->clear();
- }
- }
-
- void getArray(Vector<sp<MediaCodecBuffer>> *array) const final {
- mImpl.getArray(array);
- }
-
- void realloc(const std::shared_ptr<C2Buffer> &c2buffer) {
- std::function<sp<Codec2Buffer>()> alloc;
- switch (c2buffer->data().type()) {
- case C2BufferData::LINEAR: {
- uint32_t size = kLinearBufferSize;
- const size_t blockSize = c2buffer->data().linearBlocks().front().size();
- if (blockSize < kMaxLinearBufferSize / 2) {
- size = blockSize * 2;
- } else {
- size = kMaxLinearBufferSize;
- }
- alloc = [format = mFormat, size] {
- return new LocalLinearBuffer(format, new ABuffer(size));
- };
- break;
- }
-
- // TODO: add support
- case C2BufferData::GRAPHIC: FALLTHROUGH_INTENDED;
-
- case C2BufferData::INVALID: FALLTHROUGH_INTENDED;
- case C2BufferData::LINEAR_CHUNKS: FALLTHROUGH_INTENDED;
- case C2BufferData::GRAPHIC_CHUNKS: FALLTHROUGH_INTENDED;
- default:
- ALOGD("Unsupported type: %d", (int)c2buffer->data().type());
- return;
- }
- mImpl.realloc(alloc);
- }
-
-private:
- BuffersArrayImpl mImpl;
-};
-
-class FlexOutputBuffers : public CCodecBufferChannel::OutputBuffers {
-public:
- FlexOutputBuffers(const char *componentName, const char *name = "Output[]")
- : OutputBuffers(componentName, name),
- mImpl(mName) { }
-
- status_t registerBuffer(
- const std::shared_ptr<C2Buffer> &buffer,
- size_t *index,
- sp<MediaCodecBuffer> *clientBuffer) override {
- sp<Codec2Buffer> newBuffer = wrap(buffer);
- newBuffer->setFormat(mFormat);
- *index = mImpl.assignSlot(newBuffer);
- *clientBuffer = newBuffer;
- ALOGV("[%s] registered buffer %zu", mName, *index);
- return OK;
- }
-
- status_t registerCsd(
- const C2StreamCsdInfo::output *csd,
- size_t *index,
- sp<MediaCodecBuffer> *clientBuffer) final {
- sp<Codec2Buffer> newBuffer = new LocalLinearBuffer(
- mFormat, ABuffer::CreateAsCopy(csd->m.value, csd->flexCount()));
- *index = mImpl.assignSlot(newBuffer);
- *clientBuffer = newBuffer;
- return OK;
- }
-
- bool releaseBuffer(
- const sp<MediaCodecBuffer> &buffer,
- std::shared_ptr<C2Buffer> *c2buffer) override {
- return mImpl.releaseSlot(buffer, c2buffer, true);
- }
-
- void flush(
- const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
- (void) flushedWork;
- // This is no-op by default unless we're in array mode where we need to keep
- // track of the flushed work.
- }
-
- std::unique_ptr<CCodecBufferChannel::OutputBuffers> toArrayMode(
- size_t size) override {
- std::unique_ptr<OutputBuffersArray> array(new OutputBuffersArray(mComponentName.c_str()));
- array->setFormat(mFormat);
- array->transferSkipCutBuffer(mSkipCutBuffer);
- array->initialize(
- mImpl,
- size,
- [this]() { return allocateArrayBuffer(); });
- return std::move(array);
- }
-
- /**
- * Return an appropriate Codec2Buffer object for the type of buffers.
- *
- * \param buffer C2Buffer object to wrap.
- *
- * \return appropriate Codec2Buffer object to wrap |buffer|.
- */
- virtual sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) = 0;
-
- /**
- * Return an appropriate Codec2Buffer object for the type of buffers, to be
- * used as an empty array buffer.
- *
- * \return appropriate Codec2Buffer object which can copy() from C2Buffers.
- */
- virtual sp<Codec2Buffer> allocateArrayBuffer() = 0;
-
-private:
- FlexBuffersImpl mImpl;
-};
-
-class LinearOutputBuffers : public FlexOutputBuffers {
-public:
- LinearOutputBuffers(const char *componentName, const char *name = "1D-Output")
- : FlexOutputBuffers(componentName, name) { }
-
- void flush(
- const std::list<std::unique_ptr<C2Work>> &flushedWork) override {
- if (mSkipCutBuffer != nullptr) {
- mSkipCutBuffer->clear();
- }
- FlexOutputBuffers::flush(flushedWork);
- }
-
- sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
- if (buffer == nullptr) {
- ALOGV("[%s] using a dummy buffer", mName);
- return new LocalLinearBuffer(mFormat, new ABuffer(0));
- }
- if (buffer->data().type() != C2BufferData::LINEAR) {
- ALOGV("[%s] non-linear buffer %d", mName, buffer->data().type());
- // We expect linear output buffers from the component.
- return nullptr;
- }
- if (buffer->data().linearBlocks().size() != 1u) {
- ALOGV("[%s] no linear buffers", mName);
- // We expect one and only one linear block from the component.
- return nullptr;
- }
- sp<Codec2Buffer> clientBuffer = ConstLinearBlockBuffer::Allocate(mFormat, buffer);
- submit(clientBuffer);
- return clientBuffer;
- }
-
- sp<Codec2Buffer> allocateArrayBuffer() override {
- // TODO: proper max output size
- return new LocalLinearBuffer(mFormat, new ABuffer(kLinearBufferSize));
- }
-};
-
-class GraphicOutputBuffers : public FlexOutputBuffers {
-public:
- GraphicOutputBuffers(const char *componentName, const char *name = "2D-Output")
- : FlexOutputBuffers(componentName, name) { }
-
- sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
- return new DummyContainerBuffer(mFormat, buffer);
- }
-
- sp<Codec2Buffer> allocateArrayBuffer() override {
- return new DummyContainerBuffer(mFormat);
- }
-};
-
-class RawGraphicOutputBuffers : public FlexOutputBuffers {
-public:
- RawGraphicOutputBuffers(const char *componentName, const char *name = "2D-BB-Output")
- : FlexOutputBuffers(componentName, name),
- mLocalBufferPool(LocalBufferPool::Create(
- kMaxLinearBufferSize * kMinOutputBufferArraySize)) { }
- ~RawGraphicOutputBuffers() override = default;
-
- sp<Codec2Buffer> wrap(const std::shared_ptr<C2Buffer> &buffer) override {
- if (buffer == nullptr) {
- sp<Codec2Buffer> c2buffer = ConstGraphicBlockBuffer::AllocateEmpty(
- mFormat,
- [lbp = mLocalBufferPool](size_t capacity) {
- return lbp->newBuffer(capacity);
- });
- c2buffer->setRange(0, 0);
- return c2buffer;
- } else {
- return ConstGraphicBlockBuffer::Allocate(
- mFormat,
- buffer,
- [lbp = mLocalBufferPool](size_t capacity) {
- return lbp->newBuffer(capacity);
- });
- }
- }
-
- sp<Codec2Buffer> allocateArrayBuffer() override {
- return ConstGraphicBlockBuffer::AllocateEmpty(
- mFormat,
- [lbp = mLocalBufferPool](size_t capacity) {
- return lbp->newBuffer(capacity);
- });
- }
-
-private:
- std::shared_ptr<LocalBufferPool> mLocalBufferPool;
-};
-
-} // namespace
-
-CCodecBufferChannel::QueueGuard::QueueGuard(
- CCodecBufferChannel::QueueSync &sync) : mSync(sync) {
- Mutex::Autolock l(mSync.mGuardLock);
- // At this point it's guaranteed that mSync is not under state transition,
- // as we are holding its mutex.
-
- Mutexed<CCodecBufferChannel::QueueSync::Counter>::Locked count(mSync.mCount);
- if (count->value == -1) {
- mRunning = false;
- } else {
- ++count->value;
- mRunning = true;
- }
-}
-
-CCodecBufferChannel::QueueGuard::~QueueGuard() {
- if (mRunning) {
- // We are not holding mGuardLock at this point so that QueueSync::stop() can
- // keep holding the lock until mCount reaches zero.
- Mutexed<CCodecBufferChannel::QueueSync::Counter>::Locked count(mSync.mCount);
- --count->value;
- count->cond.broadcast();
- }
-}
-
-void CCodecBufferChannel::QueueSync::start() {
- Mutex::Autolock l(mGuardLock);
- // If stopped, it goes to running state; otherwise no-op.
- Mutexed<Counter>::Locked count(mCount);
- if (count->value == -1) {
- count->value = 0;
- }
-}
-
-void CCodecBufferChannel::QueueSync::stop() {
- Mutex::Autolock l(mGuardLock);
- Mutexed<Counter>::Locked count(mCount);
- if (count->value == -1) {
- // no-op
- return;
- }
- // Holding mGuardLock here blocks creation of additional QueueGuard objects, so
- // mCount can only decrement. In other words, threads that acquired the lock
- // are allowed to finish execution but additional threads trying to acquire
- // the lock at this point will block, and then get QueueGuard at STOPPED
- // state.
- while (count->value != 0) {
- count.waitForCondition(count->cond);
- }
- count->value = -1;
-}
-
-// CCodecBufferChannel::PipelineCapacity
-
-CCodecBufferChannel::PipelineCapacity::PipelineCapacity()
- : input(0), component(0),
- mName("<UNKNOWN COMPONENT>") {
-}
-
-void CCodecBufferChannel::PipelineCapacity::initialize(
- int newInput,
- int newComponent,
- const char* newName,
- const char* callerTag) {
- input.store(newInput, std::memory_order_relaxed);
- component.store(newComponent, std::memory_order_relaxed);
- mName = newName;
- ALOGV("[%s] %s -- PipelineCapacity::initialize(): "
- "pipeline availability initialized ==> "
- "input = %d, component = %d",
- mName, callerTag ? callerTag : "*",
- newInput, newComponent);
-}
-
-bool CCodecBufferChannel::PipelineCapacity::allocate(const char* callerTag) {
- int prevInput = input.fetch_sub(1, std::memory_order_relaxed);
- int prevComponent = component.fetch_sub(1, std::memory_order_relaxed);
- if (prevInput > 0 && prevComponent > 0) {
- ALOGV("[%s] %s -- PipelineCapacity::allocate() returns true: "
- "pipeline availability -1 all ==> "
- "input = %d, component = %d",
- mName, callerTag ? callerTag : "*",
- prevInput - 1,
- prevComponent - 1);
- return true;
- }
- input.fetch_add(1, std::memory_order_relaxed);
- component.fetch_add(1, std::memory_order_relaxed);
- ALOGV("[%s] %s -- PipelineCapacity::allocate() returns false: "
- "pipeline availability unchanged ==> "
- "input = %d, component = %d",
- mName, callerTag ? callerTag : "*",
- prevInput,
- prevComponent);
- return false;
-}
-
-void CCodecBufferChannel::PipelineCapacity::free(const char* callerTag) {
- int prevInput = input.fetch_add(1, std::memory_order_relaxed);
- int prevComponent = component.fetch_add(1, std::memory_order_relaxed);
- ALOGV("[%s] %s -- PipelineCapacity::free(): "
- "pipeline availability +1 all ==> "
- "input = %d, component = %d",
- mName, callerTag ? callerTag : "*",
- prevInput + 1,
- prevComponent + 1);
-}
-
-int CCodecBufferChannel::PipelineCapacity::freeInputSlots(
- size_t numDiscardedInputBuffers,
- const char* callerTag) {
- int prevInput = input.fetch_add(numDiscardedInputBuffers,
- std::memory_order_relaxed);
- ALOGV("[%s] %s -- PipelineCapacity::freeInputSlots(%zu): "
- "pipeline availability +%zu input ==> "
- "input = %d, component = %d",
- mName, callerTag ? callerTag : "*",
- numDiscardedInputBuffers,
- numDiscardedInputBuffers,
- prevInput + static_cast<int>(numDiscardedInputBuffers),
- component.load(std::memory_order_relaxed));
- return prevInput + static_cast<int>(numDiscardedInputBuffers);
-}
-
-int CCodecBufferChannel::PipelineCapacity::freeComponentSlot(
- const char* callerTag) {
- int prevComponent = component.fetch_add(1, std::memory_order_relaxed);
- ALOGV("[%s] %s -- PipelineCapacity::freeComponentSlot(): "
- "pipeline availability +1 component ==> "
- "input = %d, component = %d",
- mName, callerTag ? callerTag : "*",
- input.load(std::memory_order_relaxed),
- prevComponent + 1);
- return prevComponent + 1;
-}
-
-// CCodecBufferChannel::ReorderStash
-
-CCodecBufferChannel::ReorderStash::ReorderStash() {
- clear();
-}
-
-void CCodecBufferChannel::ReorderStash::clear() {
- mPending.clear();
- mStash.clear();
- mDepth = 0;
- mKey = C2Config::ORDINAL;
-}
-
-void CCodecBufferChannel::ReorderStash::setDepth(uint32_t depth) {
- mPending.splice(mPending.end(), mStash);
- mDepth = depth;
-}
-void CCodecBufferChannel::ReorderStash::setKey(C2Config::ordinal_key_t key) {
- mPending.splice(mPending.end(), mStash);
- mKey = key;
-}
-
-bool CCodecBufferChannel::ReorderStash::pop(Entry *entry) {
- if (mPending.empty()) {
- return false;
- }
- entry->buffer = mPending.front().buffer;
- entry->timestamp = mPending.front().timestamp;
- entry->flags = mPending.front().flags;
- entry->ordinal = mPending.front().ordinal;
- mPending.pop_front();
- return true;
-}
-
-void CCodecBufferChannel::ReorderStash::emplace(
- const std::shared_ptr<C2Buffer> &buffer,
- int64_t timestamp,
- int32_t flags,
- const C2WorkOrdinalStruct &ordinal) {
- for (auto it = mStash.begin(); it != mStash.end(); ++it) {
- if (less(ordinal, it->ordinal)) {
- mStash.emplace(it, buffer, timestamp, flags, ordinal);
- return;
- }
- }
- mStash.emplace_back(buffer, timestamp, flags, ordinal);
- while (!mStash.empty() && mStash.size() > mDepth) {
- mPending.push_back(mStash.front());
- mStash.pop_front();
- }
-}
-
-void CCodecBufferChannel::ReorderStash::defer(
- const CCodecBufferChannel::ReorderStash::Entry &entry) {
- mPending.push_front(entry);
-}
-
-bool CCodecBufferChannel::ReorderStash::hasPending() const {
- return !mPending.empty();
-}
-
-bool CCodecBufferChannel::ReorderStash::less(
- const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2) {
- switch (mKey) {
- case C2Config::ORDINAL: return o1.frameIndex < o2.frameIndex;
- case C2Config::TIMESTAMP: return o1.timestamp < o2.timestamp;
- case C2Config::CUSTOM: return o1.customOrdinal < o2.customOrdinal;
- default:
- ALOGD("Unrecognized key; default to timestamp");
- return o1.frameIndex < o2.frameIndex;
- }
-}
-
-// CCodecBufferChannel
-
-CCodecBufferChannel::CCodecBufferChannel(
- const std::shared_ptr<CCodecCallback> &callback)
- : mHeapSeqNum(-1),
- mCCodecCallback(callback),
- mFrameIndex(0u),
- mFirstValidFrameIndex(0u),
- mMetaMode(MODE_NONE),
- mAvailablePipelineCapacity(),
- mInputMetEos(false) {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- buffers->reset(new DummyInputBuffers(""));
-}
-
-CCodecBufferChannel::~CCodecBufferChannel() {
- if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
- mCrypto->unsetHeap(mHeapSeqNum);
- }
-}
-
-void CCodecBufferChannel::setComponent(
- const std::shared_ptr<Codec2Client::Component> &component) {
- mComponent = component;
- mComponentName = component->getName() + StringPrintf("#%d", int(uintptr_t(component.get()) % 997));
- mName = mComponentName.c_str();
-}
-
-status_t CCodecBufferChannel::setInputSurface(
- const std::shared_ptr<InputSurfaceWrapper> &surface) {
- ALOGV("[%s] setInputSurface", mName);
- mInputSurface = surface;
- return mInputSurface->connect(mComponent);
-}
-
-status_t CCodecBufferChannel::signalEndOfInputStream() {
- if (mInputSurface == nullptr) {
- return INVALID_OPERATION;
- }
- return mInputSurface->signalEndOfInputStream();
-}
-
-status_t CCodecBufferChannel::queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer) {
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
- if (mInputMetEos) {
- ALOGD("[%s] buffers after EOS ignored (%lld us)", mName, (long long)timeUs);
- return OK;
- }
-
- int32_t flags = 0;
- int32_t tmp = 0;
- bool eos = false;
- if (buffer->meta()->findInt32("eos", &tmp) && tmp) {
- eos = true;
- mInputMetEos = true;
- ALOGV("[%s] input EOS", mName);
- }
- if (buffer->meta()->findInt32("csd", &tmp) && tmp) {
- flags |= C2FrameData::FLAG_CODEC_CONFIG;
- }
- ALOGV("[%s] queueInputBuffer: buffer->size() = %zu", mName, buffer->size());
- std::unique_ptr<C2Work> work(new C2Work);
- work->input.ordinal.timestamp = timeUs;
- work->input.ordinal.frameIndex = mFrameIndex++;
- // WORKAROUND: until codecs support handling work after EOS and max output sizing, use timestamp
- // manipulation to achieve image encoding via video codec, and to constrain encoded output.
- // Keep client timestamp in customOrdinal
- work->input.ordinal.customOrdinal = timeUs;
- work->input.buffers.clear();
-
- if (buffer->size() > 0u) {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- std::shared_ptr<C2Buffer> c2buffer;
- if (!(*buffers)->releaseBuffer(buffer, &c2buffer, false)) {
- return -ENOENT;
- }
- work->input.buffers.push_back(c2buffer);
- } else {
- mAvailablePipelineCapacity.freeInputSlots(1, "queueInputBufferInternal");
- if (eos) {
- flags |= C2FrameData::FLAG_END_OF_STREAM;
- }
- }
- work->input.flags = (C2FrameData::flags_t)flags;
- // TODO: fill info's
-
- work->input.configUpdate = std::move(mParamsToBeSet);
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- c2_status_t err = mComponent->queue(&items);
-
- if (err == C2_OK && eos && buffer->size() > 0u) {
- mCCodecCallback->onWorkQueued(false);
- work.reset(new C2Work);
- work->input.ordinal.timestamp = timeUs;
- work->input.ordinal.frameIndex = mFrameIndex++;
- // WORKAROUND: keep client timestamp in customOrdinal
- work->input.ordinal.customOrdinal = timeUs;
- work->input.buffers.clear();
- work->input.flags = C2FrameData::FLAG_END_OF_STREAM;
-
- items.clear();
- items.push_back(std::move(work));
- err = mComponent->queue(&items);
- }
- if (err == C2_OK) {
- mCCodecCallback->onWorkQueued(eos);
-
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- bool released = (*buffers)->releaseBuffer(buffer, nullptr, true);
- ALOGV("[%s] queueInputBuffer: buffer %sreleased", mName, released ? "" : "not ");
- }
-
- feedInputBufferIfAvailableInternal();
- return err;
-}
-
-status_t CCodecBufferChannel::setParameters(std::vector<std::unique_ptr<C2Param>> &params) {
- QueueGuard guard(mSync);
- if (!guard.isRunning()) {
- ALOGD("[%s] setParameters is only supported in the running state.", mName);
- return -ENOSYS;
- }
- mParamsToBeSet.insert(mParamsToBeSet.end(),
- std::make_move_iterator(params.begin()),
- std::make_move_iterator(params.end()));
- params.clear();
- return OK;
-}
-
-status_t CCodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
- QueueGuard guard(mSync);
- if (!guard.isRunning()) {
- ALOGD("[%s] No more buffers should be queued at current state.", mName);
- return -ENOSYS;
- }
- return queueInputBufferInternal(buffer);
-}
-
-status_t CCodecBufferChannel::queueSecureInputBuffer(
- const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key,
- const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
- const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- AString *errorDetailMsg) {
- QueueGuard guard(mSync);
- if (!guard.isRunning()) {
- ALOGD("[%s] No more buffers should be queued at current state.", mName);
- return -ENOSYS;
- }
-
- if (!hasCryptoOrDescrambler()) {
- return -ENOSYS;
- }
- sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get());
-
- ssize_t result = -1;
- ssize_t codecDataOffset = 0;
- if (mCrypto != nullptr) {
- ICrypto::DestinationBuffer destination;
- if (secure) {
- destination.mType = ICrypto::kDestinationTypeNativeHandle;
- destination.mHandle = encryptedBuffer->handle();
- } else {
- destination.mType = ICrypto::kDestinationTypeSharedMemory;
- destination.mSharedMemory = mDecryptDestination;
- }
- ICrypto::SourceBuffer source;
- encryptedBuffer->fillSourceBuffer(&source);
- result = mCrypto->decrypt(
- key, iv, mode, pattern, source, buffer->offset(),
- subSamples, numSubSamples, destination, errorDetailMsg);
- if (result < 0) {
- return result;
- }
- if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
- encryptedBuffer->copyDecryptedContent(mDecryptDestination, result);
- }
- } else {
- // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
- // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
- hidl_vec<SubSample> hidlSubSamples;
- hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
-
- hardware::cas::native::V1_0::SharedBuffer srcBuffer;
- encryptedBuffer->fillSourceBuffer(&srcBuffer);
-
- DestinationBuffer dstBuffer;
- if (secure) {
- dstBuffer.type = BufferType::NATIVE_HANDLE;
- dstBuffer.secureMemory = hidl_handle(encryptedBuffer->handle());
- } else {
- dstBuffer.type = BufferType::SHARED_MEMORY;
- dstBuffer.nonsecureMemory = srcBuffer;
- }
-
- CasStatus status = CasStatus::OK;
- hidl_string detailedError;
- ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;
-
- if (key != nullptr) {
- sctrl = (ScramblingControl)key[0];
- // Adjust for the PES offset
- codecDataOffset = key[2] | (key[3] << 8);
- }
-
- auto returnVoid = mDescrambler->descramble(
- sctrl,
- hidlSubSamples,
- srcBuffer,
- 0,
- dstBuffer,
- 0,
- [&status, &result, &detailedError] (
- CasStatus _status, uint32_t _bytesWritten,
- const hidl_string& _detailedError) {
- status = _status;
- result = (ssize_t)_bytesWritten;
- detailedError = _detailedError;
- });
-
- if (!returnVoid.isOk() || status != CasStatus::OK || result < 0) {
- ALOGI("[%s] descramble failed, trans=%s, status=%d, result=%zd",
- mName, returnVoid.description().c_str(), status, result);
- return UNKNOWN_ERROR;
- }
-
- if (result < codecDataOffset) {
- ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
- return BAD_VALUE;
- }
-
- ALOGV("[%s] descramble succeeded, %zd bytes", mName, result);
-
- if (dstBuffer.type == BufferType::SHARED_MEMORY) {
- encryptedBuffer->copyDecryptedContentFromMemory(result);
- }
- }
-
- buffer->setRange(codecDataOffset, result - codecDataOffset);
- return queueInputBufferInternal(buffer);
-}
-
-void CCodecBufferChannel::feedInputBufferIfAvailable() {
- QueueGuard guard(mSync);
- if (!guard.isRunning()) {
- ALOGV("[%s] We're not running --- no input buffer reported", mName);
- return;
- }
- feedInputBufferIfAvailableInternal();
-}
-
-void CCodecBufferChannel::feedInputBufferIfAvailableInternal() {
- while (!mInputMetEos &&
- !mReorderStash.lock()->hasPending() &&
- mAvailablePipelineCapacity.allocate("feedInputBufferIfAvailable")) {
- sp<MediaCodecBuffer> inBuffer;
- size_t index;
- {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if (!(*buffers)->requestNewBuffer(&index, &inBuffer)) {
- ALOGV("[%s] no new buffer available", mName);
- mAvailablePipelineCapacity.free("feedInputBufferIfAvailable");
- break;
- }
- }
- ALOGV("[%s] new input index = %zu [%p]", mName, index, inBuffer.get());
- mCallback->onInputBufferAvailable(index, inBuffer);
- }
-}
-
-status_t CCodecBufferChannel::renderOutputBuffer(
- const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) {
- ALOGV("[%s] renderOutputBuffer: %p", mName, buffer.get());
- std::shared_ptr<C2Buffer> c2Buffer;
- bool released = false;
- {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if (*buffers) {
- released = (*buffers)->releaseBuffer(buffer, &c2Buffer);
- }
- }
- // NOTE: some apps try to releaseOutputBuffer() with timestamp and/or render
- // set to true.
- sendOutputBuffers();
- // input buffer feeding may have been gated by pending output buffers
- feedInputBufferIfAvailable();
- if (!c2Buffer) {
- if (released) {
- ALOGD("[%s] The app is calling releaseOutputBuffer() with "
- "timestamp or render=true with non-video buffers. Apps should "
- "call releaseOutputBuffer() with render=false for those.",
- mName);
- }
- return INVALID_OPERATION;
- }
-
-#if 0
- const std::vector<std::shared_ptr<const C2Info>> infoParams = c2Buffer->info();
- ALOGV("[%s] queuing gfx buffer with %zu infos", mName, infoParams.size());
- for (const std::shared_ptr<const C2Info> &info : infoParams) {
- AString res;
- for (size_t ix = 0; ix + 3 < info->size(); ix += 4) {
- if (ix) res.append(", ");
- res.append(*((int32_t*)info.get() + (ix / 4)));
- }
- ALOGV(" [%s]", res.c_str());
- }
-#endif
- std::shared_ptr<const C2StreamRotationInfo::output> rotation =
- std::static_pointer_cast<const C2StreamRotationInfo::output>(
- c2Buffer->getInfo(C2StreamRotationInfo::output::PARAM_TYPE));
- bool flip = rotation && (rotation->flip & 1);
- uint32_t quarters = ((rotation ? rotation->value : 0) / 90) & 3;
- uint32_t transform = 0;
- switch (quarters) {
- case 0: // no rotation
- transform = flip ? HAL_TRANSFORM_FLIP_H : 0;
- break;
- case 1: // 90 degrees counter-clockwise
- transform = flip ? (HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90)
- : HAL_TRANSFORM_ROT_270;
- break;
- case 2: // 180 degrees
- transform = flip ? HAL_TRANSFORM_FLIP_V : HAL_TRANSFORM_ROT_180;
- break;
- case 3: // 90 degrees clockwise
- transform = flip ? (HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90)
- : HAL_TRANSFORM_ROT_90;
- break;
- }
-
- std::shared_ptr<const C2StreamSurfaceScalingInfo::output> surfaceScaling =
- std::static_pointer_cast<const C2StreamSurfaceScalingInfo::output>(
- c2Buffer->getInfo(C2StreamSurfaceScalingInfo::output::PARAM_TYPE));
- uint32_t videoScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
- if (surfaceScaling) {
- videoScalingMode = surfaceScaling->value;
- }
-
- // Use dataspace from format as it has the default aspects already applied
- android_dataspace_t dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
- (void)buffer->format()->findInt32("android._dataspace", (int32_t *)&dataSpace);
-
- // HDR static info
- std::shared_ptr<const C2StreamHdrStaticInfo::output> hdrStaticInfo =
- std::static_pointer_cast<const C2StreamHdrStaticInfo::output>(
- c2Buffer->getInfo(C2StreamHdrStaticInfo::output::PARAM_TYPE));
-
- // HDR10 plus info
- std::shared_ptr<const C2StreamHdr10PlusInfo::output> hdr10PlusInfo =
- std::static_pointer_cast<const C2StreamHdr10PlusInfo::output>(
- c2Buffer->getInfo(C2StreamHdr10PlusInfo::output::PARAM_TYPE));
-
- {
- Mutexed<OutputSurface>::Locked output(mOutputSurface);
- if (output->surface == nullptr) {
- ALOGI("[%s] cannot render buffer without surface", mName);
- return OK;
- }
- }
-
- std::vector<C2ConstGraphicBlock> blocks = c2Buffer->data().graphicBlocks();
- if (blocks.size() != 1u) {
- ALOGD("[%s] expected 1 graphic block, but got %zu", mName, blocks.size());
- return UNKNOWN_ERROR;
- }
- const C2ConstGraphicBlock &block = blocks.front();
-
- // TODO: revisit this after C2Fence implementation.
- android::IGraphicBufferProducer::QueueBufferInput qbi(
- timestampNs,
- false, // droppable
- dataSpace,
- Rect(blocks.front().crop().left,
- blocks.front().crop().top,
- blocks.front().crop().right(),
- blocks.front().crop().bottom()),
- videoScalingMode,
- transform,
- Fence::NO_FENCE, 0);
- if (hdrStaticInfo || hdr10PlusInfo) {
- HdrMetadata hdr;
- if (hdrStaticInfo) {
- struct android_smpte2086_metadata smpte2086_meta = {
- .displayPrimaryRed = {
- hdrStaticInfo->mastering.red.x, hdrStaticInfo->mastering.red.y
- },
- .displayPrimaryGreen = {
- hdrStaticInfo->mastering.green.x, hdrStaticInfo->mastering.green.y
- },
- .displayPrimaryBlue = {
- hdrStaticInfo->mastering.blue.x, hdrStaticInfo->mastering.blue.y
- },
- .whitePoint = {
- hdrStaticInfo->mastering.white.x, hdrStaticInfo->mastering.white.y
- },
- .maxLuminance = hdrStaticInfo->mastering.maxLuminance,
- .minLuminance = hdrStaticInfo->mastering.minLuminance,
- };
-
- struct android_cta861_3_metadata cta861_meta = {
- .maxContentLightLevel = hdrStaticInfo->maxCll,
- .maxFrameAverageLightLevel = hdrStaticInfo->maxFall,
- };
-
- hdr.validTypes = HdrMetadata::SMPTE2086 | HdrMetadata::CTA861_3;
- hdr.smpte2086 = smpte2086_meta;
- hdr.cta8613 = cta861_meta;
- }
- if (hdr10PlusInfo) {
- hdr.validTypes |= HdrMetadata::HDR10PLUS;
- hdr.hdr10plus.assign(
- hdr10PlusInfo->m.value,
- hdr10PlusInfo->m.value + hdr10PlusInfo->flexCount());
- }
- qbi.setHdrMetadata(hdr);
- }
- // we don't have dirty regions
- qbi.setSurfaceDamage(Region::INVALID_REGION);
- android::IGraphicBufferProducer::QueueBufferOutput qbo;
- status_t result = mComponent->queueToOutputSurface(block, qbi, &qbo);
- if (result != OK) {
- ALOGI("[%s] queueBuffer failed: %d", mName, result);
- return result;
- }
- ALOGV("[%s] queue buffer successful", mName);
-
- int64_t mediaTimeUs = 0;
- (void)buffer->meta()->findInt64("timeUs", &mediaTimeUs);
- mCCodecCallback->onOutputFramesRendered(mediaTimeUs, timestampNs);
-
- return OK;
-}
-
-status_t CCodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
- ALOGV("[%s] discardBuffer: %p", mName, buffer.get());
- bool released = false;
- {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr, true)) {
- buffers.unlock();
- released = true;
- mAvailablePipelineCapacity.freeInputSlots(1, "discardBuffer");
- }
- }
- {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if (*buffers && (*buffers)->releaseBuffer(buffer, nullptr)) {
- buffers.unlock();
- released = true;
- }
- }
- if (released) {
- sendOutputBuffers();
- feedInputBufferIfAvailable();
- } else {
- ALOGD("[%s] MediaCodec discarded an unknown buffer", mName);
- }
- return OK;
-}
-
-void CCodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
- array->clear();
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
-
- if (!(*buffers)->isArrayMode()) {
- *buffers = (*buffers)->toArrayMode(kMinInputBufferArraySize);
- }
-
- (*buffers)->getArray(array);
-}
-
-void CCodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
- array->clear();
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
- if (!(*buffers)->isArrayMode()) {
- *buffers = (*buffers)->toArrayMode(kMinOutputBufferArraySize);
- }
-
- (*buffers)->getArray(array);
-}
-
-status_t CCodecBufferChannel::start(
- const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
- C2StreamBufferTypeSetting::input iStreamFormat(0u);
- C2StreamBufferTypeSetting::output oStreamFormat(0u);
- C2PortReorderBufferDepthTuning::output reorderDepth;
- C2PortReorderKeySetting::output reorderKey;
- c2_status_t err = mComponent->query(
- {
- &iStreamFormat,
- &oStreamFormat,
- &reorderDepth,
- &reorderKey,
- },
- {},
- C2_DONT_BLOCK,
- nullptr);
- if (err == C2_BAD_INDEX) {
- if (!iStreamFormat || !oStreamFormat) {
- return UNKNOWN_ERROR;
- }
- } else if (err != C2_OK) {
- return UNKNOWN_ERROR;
- }
-
- {
- Mutexed<ReorderStash>::Locked reorder(mReorderStash);
- reorder->clear();
- if (reorderDepth) {
- reorder->setDepth(reorderDepth.value);
- }
- if (reorderKey) {
- reorder->setKey(reorderKey.value);
- }
- }
- // TODO: get this from input format
- bool secure = mComponent->getName().find(".secure") != std::string::npos;
-
- std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
- int poolMask = property_get_int32(
- "debug.stagefright.c2-poolmask",
- 1 << C2PlatformAllocatorStore::ION |
- 1 << C2PlatformAllocatorStore::BUFFERQUEUE);
-
- if (inputFormat != nullptr) {
- bool graphic = (iStreamFormat.value == C2FormatVideo);
- std::shared_ptr<C2BlockPool> pool;
- {
- Mutexed<BlockPools>::Locked pools(mBlockPools);
-
- // set default allocator ID.
- pools->inputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
- : C2PlatformAllocatorStore::ION;
-
- // query C2PortAllocatorsTuning::input from component. If an allocator ID is obtained
- // from component, create the input block pool with given ID. Otherwise, use default IDs.
- std::vector<std::unique_ptr<C2Param>> params;
- err = mComponent->query({ },
- { C2PortAllocatorsTuning::input::PARAM_TYPE },
- C2_DONT_BLOCK,
- &params);
- if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
- ALOGD("[%s] Query input allocators returned %zu params => %s (%u)",
- mName, params.size(), asString(err), err);
- } else if (err == C2_OK && params.size() == 1) {
- C2PortAllocatorsTuning::input *inputAllocators =
- C2PortAllocatorsTuning::input::From(params[0].get());
- if (inputAllocators && inputAllocators->flexCount() > 0) {
- std::shared_ptr<C2Allocator> allocator;
- // verify allocator IDs and resolve default allocator
- allocatorStore->fetchAllocator(inputAllocators->m.values[0], &allocator);
- if (allocator) {
- pools->inputAllocatorId = allocator->getId();
- } else {
- ALOGD("[%s] component requested invalid input allocator ID %u",
- mName, inputAllocators->m.values[0]);
- }
- }
- }
-
- // TODO: use C2Component wrapper to associate this pool with ourselves
- if ((poolMask >> pools->inputAllocatorId) & 1) {
- err = CreateCodec2BlockPool(pools->inputAllocatorId, nullptr, &pool);
- ALOGD("[%s] Created input block pool with allocatorID %u => poolID %llu - %s (%d)",
- mName, pools->inputAllocatorId,
- (unsigned long long)(pool ? pool->getLocalId() : 111000111),
- asString(err), err);
- } else {
- err = C2_NOT_FOUND;
- }
- if (err != C2_OK) {
- C2BlockPool::local_id_t inputPoolId =
- graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR;
- err = GetCodec2BlockPool(inputPoolId, nullptr, &pool);
- ALOGD("[%s] Using basic input block pool with poolID %llu => got %llu - %s (%d)",
- mName, (unsigned long long)inputPoolId,
- (unsigned long long)(pool ? pool->getLocalId() : 111000111),
- asString(err), err);
- if (err != C2_OK) {
- return NO_MEMORY;
- }
- }
- pools->inputPool = pool;
- }
-
- bool forceArrayMode = false;
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if (graphic) {
- if (mInputSurface) {
- buffers->reset(new DummyInputBuffers(mName));
- } else if (mMetaMode == MODE_ANW) {
- buffers->reset(new GraphicMetadataInputBuffers(mName));
- } else {
- buffers->reset(new GraphicInputBuffers(mName));
- }
- } else {
- if (hasCryptoOrDescrambler()) {
- int32_t capacity = kLinearBufferSize;
- (void)inputFormat->findInt32(KEY_MAX_INPUT_SIZE, &capacity);
- if ((size_t)capacity > kMaxLinearBufferSize) {
- ALOGD("client requested %d, capped to %zu", capacity, kMaxLinearBufferSize);
- capacity = kMaxLinearBufferSize;
- }
- if (mDealer == nullptr) {
- mDealer = new MemoryDealer(
- align(capacity, MemoryDealer::getAllocationAlignment())
- * (kMinInputBufferArraySize + 1),
- "EncryptedLinearInputBuffers");
- mDecryptDestination = mDealer->allocate((size_t)capacity);
- }
- if (mCrypto != nullptr && mHeapSeqNum < 0) {
- mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap());
- } else {
- mHeapSeqNum = -1;
- }
- buffers->reset(new EncryptedLinearInputBuffers(
- secure, mDealer, mCrypto, mHeapSeqNum, (size_t)capacity, mName));
- forceArrayMode = true;
- } else {
- buffers->reset(new LinearInputBuffers(mName));
- }
- }
- (*buffers)->setFormat(inputFormat);
-
- if (err == C2_OK) {
- (*buffers)->setPool(pool);
- } else {
- // TODO: error
- }
-
- if (forceArrayMode) {
- *buffers = (*buffers)->toArrayMode(kMinInputBufferArraySize);
- }
- }
-
- if (outputFormat != nullptr) {
- sp<IGraphicBufferProducer> outputSurface;
- uint32_t outputGeneration;
- {
- Mutexed<OutputSurface>::Locked output(mOutputSurface);
- outputSurface = output->surface ?
- output->surface->getIGraphicBufferProducer() : nullptr;
- outputGeneration = output->generation;
- }
-
- bool graphic = (oStreamFormat.value == C2FormatVideo);
- C2BlockPool::local_id_t outputPoolId_;
-
- {
- Mutexed<BlockPools>::Locked pools(mBlockPools);
-
- // set default allocator ID.
- pools->outputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
- : C2PlatformAllocatorStore::ION;
-
- // query C2PortAllocatorsTuning::output from component, or use default allocator if
- // unsuccessful.
- std::vector<std::unique_ptr<C2Param>> params;
- err = mComponent->query({ },
- { C2PortAllocatorsTuning::output::PARAM_TYPE },
- C2_DONT_BLOCK,
- &params);
- if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
- ALOGD("[%s] Query output allocators returned %zu params => %s (%u)",
- mName, params.size(), asString(err), err);
- } else if (err == C2_OK && params.size() == 1) {
- C2PortAllocatorsTuning::output *outputAllocators =
- C2PortAllocatorsTuning::output::From(params[0].get());
- if (outputAllocators && outputAllocators->flexCount() > 0) {
- std::shared_ptr<C2Allocator> allocator;
- // verify allocator IDs and resolve default allocator
- allocatorStore->fetchAllocator(outputAllocators->m.values[0], &allocator);
- if (allocator) {
- pools->outputAllocatorId = allocator->getId();
- } else {
- ALOGD("[%s] component requested invalid output allocator ID %u",
- mName, outputAllocators->m.values[0]);
- }
- }
- }
-
- // use bufferqueue if outputting to a surface.
- // query C2PortSurfaceAllocatorTuning::output from component, or use default allocator
- // if unsuccessful.
- if (outputSurface) {
- params.clear();
- err = mComponent->query({ },
- { C2PortSurfaceAllocatorTuning::output::PARAM_TYPE },
- C2_DONT_BLOCK,
- &params);
- if ((err != C2_OK && err != C2_BAD_INDEX) || params.size() != 1) {
- ALOGD("[%s] Query output surface allocator returned %zu params => %s (%u)",
- mName, params.size(), asString(err), err);
- } else if (err == C2_OK && params.size() == 1) {
- C2PortSurfaceAllocatorTuning::output *surfaceAllocator =
- C2PortSurfaceAllocatorTuning::output::From(params[0].get());
- if (surfaceAllocator) {
- std::shared_ptr<C2Allocator> allocator;
- // verify allocator IDs and resolve default allocator
- allocatorStore->fetchAllocator(surfaceAllocator->value, &allocator);
- if (allocator) {
- pools->outputAllocatorId = allocator->getId();
- } else {
- ALOGD("[%s] component requested invalid surface output allocator ID %u",
- mName, surfaceAllocator->value);
- err = C2_BAD_VALUE;
- }
- }
- }
- if (pools->outputAllocatorId == C2PlatformAllocatorStore::GRALLOC
- && err != C2_OK
- && ((poolMask >> C2PlatformAllocatorStore::BUFFERQUEUE) & 1)) {
- pools->outputAllocatorId = C2PlatformAllocatorStore::BUFFERQUEUE;
- }
- }
-
- if ((poolMask >> pools->outputAllocatorId) & 1) {
- err = mComponent->createBlockPool(
- pools->outputAllocatorId, &pools->outputPoolId, &pools->outputPoolIntf);
- ALOGI("[%s] Created output block pool with allocatorID %u => poolID %llu - %s",
- mName, pools->outputAllocatorId,
- (unsigned long long)pools->outputPoolId,
- asString(err));
- } else {
- err = C2_NOT_FOUND;
- }
- if (err != C2_OK) {
- // use basic pool instead
- pools->outputPoolId =
- graphic ? C2BlockPool::BASIC_GRAPHIC : C2BlockPool::BASIC_LINEAR;
- }
-
- // Configure output block pool ID as parameter C2PortBlockPoolsTuning::output to
- // component.
- std::unique_ptr<C2PortBlockPoolsTuning::output> poolIdsTuning =
- C2PortBlockPoolsTuning::output::AllocUnique({ pools->outputPoolId });
-
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- err = mComponent->config({ poolIdsTuning.get() }, C2_MAY_BLOCK, &failures);
- ALOGD("[%s] Configured output block pool ids %llu => %s",
- mName, (unsigned long long)poolIdsTuning->m.values[0], asString(err));
- outputPoolId_ = pools->outputPoolId;
- }
-
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
-
- if (graphic) {
- if (outputSurface) {
- buffers->reset(new GraphicOutputBuffers(mName));
- } else {
- buffers->reset(new RawGraphicOutputBuffers(mName));
- }
- } else {
- buffers->reset(new LinearOutputBuffers(mName));
- }
- (*buffers)->setFormat(outputFormat->dup());
-
-
- // Try to set output surface to created block pool if given.
- if (outputSurface) {
- mComponent->setOutputSurface(
- outputPoolId_,
- outputSurface,
- outputGeneration);
- }
-
- if (oStreamFormat.value == C2BufferData::LINEAR
- && mComponentName.find("c2.qti.") == std::string::npos) {
- // WORKAROUND: if we're using early CSD workaround we convert to
- // array mode, to appease apps assuming the output
- // buffers to be of the same size.
- (*buffers) = (*buffers)->toArrayMode(kMinOutputBufferArraySize);
-
- int32_t channelCount;
- int32_t sampleRate;
- if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
- && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
- int32_t delay = 0;
- int32_t padding = 0;;
- if (!outputFormat->findInt32("encoder-delay", &delay)) {
- delay = 0;
- }
- if (!outputFormat->findInt32("encoder-padding", &padding)) {
- padding = 0;
- }
- if (delay || padding) {
- // We need write access to the buffers, and we're already in
- // array mode.
- (*buffers)->initSkipCutBuffer(delay, padding, sampleRate, channelCount);
- }
- }
- }
- }
-
- // Set up pipeline control. This has to be done after mInputBuffers and
- // mOutputBuffers are initialized to make sure that lingering callbacks
- // about buffers from the previous generation do not interfere with the
- // newly initialized pipeline capacity.
-
- // Query delays
- C2PortRequestedDelayTuning::input inputDelay;
- C2PortRequestedDelayTuning::output outputDelay;
- C2RequestedPipelineDelayTuning pipelineDelay;
-#if 0
- err = mComponent->query(
- { &inputDelay, &pipelineDelay, &outputDelay },
- {},
- C2_DONT_BLOCK,
- nullptr);
- mAvailablePipelineCapacity.initialize(
- inputDelay,
- inputDelay + pipelineDelay,
- inputDelay + pipelineDelay + outputDelay,
- mName);
-#else
- mAvailablePipelineCapacity.initialize(
- kMinInputBufferArraySize,
- kMaxPipelineCapacity,
- mName);
-#endif
-
- mInputMetEos = false;
- mSync.start();
- return OK;
-}
-
-status_t CCodecBufferChannel::requestInitialInputBuffers() {
- if (mInputSurface) {
- return OK;
- }
-
- C2StreamFormatConfig::output oStreamFormat(0u);
- c2_status_t err = mComponent->query({ &oStreamFormat }, {}, C2_DONT_BLOCK, nullptr);
- if (err != C2_OK) {
- return UNKNOWN_ERROR;
- }
- std::vector<sp<MediaCodecBuffer>> toBeQueued;
- // TODO: use proper buffer depth instead of this random value
- for (size_t i = 0; i < kMinInputBufferArraySize; ++i) {
- size_t index;
- sp<MediaCodecBuffer> buffer;
- {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- if (!(*buffers)->requestNewBuffer(&index, &buffer)) {
- if (i == 0) {
- ALOGW("[%s] start: cannot allocate memory at all", mName);
- return NO_MEMORY;
- } else {
- ALOGV("[%s] start: cannot allocate memory, only %zu buffers allocated",
- mName, i);
- }
- break;
- }
- }
- if (buffer) {
- Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
- ALOGV("[%s] input buffer %zu available", mName, index);
- bool post = true;
- if (!configs->empty()) {
- sp<ABuffer> config = configs->front();
- if (buffer->capacity() >= config->size()) {
- memcpy(buffer->base(), config->data(), config->size());
- buffer->setRange(0, config->size());
- buffer->meta()->clear();
- buffer->meta()->setInt64("timeUs", 0);
- buffer->meta()->setInt32("csd", 1);
- post = false;
- } else {
- ALOGD("[%s] buffer capacity too small for the config (%zu < %zu)",
- mName, buffer->capacity(), config->size());
- }
- } else if (oStreamFormat.value == C2BufferData::LINEAR && i == 0
- && mComponentName.find("c2.qti.") == std::string::npos) {
- // WORKAROUND: Some apps expect CSD available without queueing
- // any input. Queue an empty buffer to get the CSD.
- buffer->setRange(0, 0);
- buffer->meta()->clear();
- buffer->meta()->setInt64("timeUs", 0);
- post = false;
- }
- if (mAvailablePipelineCapacity.allocate("requestInitialInputBuffers")) {
- if (post) {
- mCallback->onInputBufferAvailable(index, buffer);
- } else {
- toBeQueued.emplace_back(buffer);
- }
- } else {
- ALOGD("[%s] pipeline is full while requesting %zu-th input buffer",
- mName, i);
- }
- }
- }
- for (const sp<MediaCodecBuffer> &buffer : toBeQueued) {
- if (queueInputBufferInternal(buffer) != OK) {
- mAvailablePipelineCapacity.freeComponentSlot("requestInitialInputBuffers");
- }
- }
- return OK;
-}
-
-void CCodecBufferChannel::stop() {
- mSync.stop();
- mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed);
- if (mInputSurface != nullptr) {
- mInputSurface.reset();
- }
-}
-
-void CCodecBufferChannel::flush(const std::list<std::unique_ptr<C2Work>> &flushedWork) {
- ALOGV("[%s] flush", mName);
- {
- Mutexed<std::list<sp<ABuffer>>>::Locked configs(mFlushedConfigs);
- for (const std::unique_ptr<C2Work> &work : flushedWork) {
- if (!(work->input.flags & C2FrameData::FLAG_CODEC_CONFIG)) {
- continue;
- }
- if (work->input.buffers.empty()
- || work->input.buffers.front()->data().linearBlocks().empty()) {
- ALOGD("[%s] no linear codec config data found", mName);
- continue;
- }
- C2ReadView view =
- work->input.buffers.front()->data().linearBlocks().front().map().get();
- if (view.error() != C2_OK) {
- ALOGD("[%s] failed to map flushed codec config data: %d", mName, view.error());
- continue;
- }
- configs->push_back(ABuffer::CreateAsCopy(view.data(), view.capacity()));
- ALOGV("[%s] stashed flushed codec config data (size=%u)", mName, view.capacity());
- }
- }
- {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- (*buffers)->flush();
- }
- {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- (*buffers)->flush(flushedWork);
- }
-}
-
-void CCodecBufferChannel::onWorkDone(
- std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
- const C2StreamInitDataInfo::output *initData,
- size_t numDiscardedInputBuffers) {
- if (handleWork(std::move(work), outputFormat, initData)) {
- mAvailablePipelineCapacity.freeInputSlots(numDiscardedInputBuffers,
- "onWorkDone");
- feedInputBufferIfAvailable();
- }
-}
-
-void CCodecBufferChannel::onInputBufferDone(
- const std::shared_ptr<C2Buffer>& buffer) {
- bool newInputSlotAvailable;
- {
- Mutexed<std::unique_ptr<InputBuffers>>::Locked buffers(mInputBuffers);
- newInputSlotAvailable = (*buffers)->expireComponentBuffer(buffer);
- if (newInputSlotAvailable) {
- mAvailablePipelineCapacity.freeInputSlots(1, "onInputBufferDone");
- }
- }
- if (newInputSlotAvailable) {
- feedInputBufferIfAvailable();
- }
-}
-
-bool CCodecBufferChannel::handleWork(
- std::unique_ptr<C2Work> work,
- const sp<AMessage> &outputFormat,
- const C2StreamInitDataInfo::output *initData) {
- if ((work->input.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) {
- // Discard frames from previous generation.
- ALOGD("[%s] Discard frames from previous generation.", mName);
- return false;
- }
-
- if (work->worklets.size() != 1u
- || !work->worklets.front()
- || !(work->worklets.front()->output.flags & C2FrameData::FLAG_INCOMPLETE)) {
- mAvailablePipelineCapacity.freeComponentSlot("handleWork");
- }
-
- if (work->result == C2_NOT_FOUND) {
- ALOGD("[%s] flushed work; ignored.", mName);
- return true;
- }
-
- if (work->result != C2_OK) {
- ALOGD("[%s] work failed to complete: %d", mName, work->result);
- mCCodecCallback->onError(work->result, ACTION_CODE_FATAL);
- return false;
- }
-
- // NOTE: MediaCodec usage supposedly have only one worklet
- if (work->worklets.size() != 1u) {
- ALOGI("[%s] onWorkDone: incorrect number of worklets: %zu",
- mName, work->worklets.size());
- mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- return false;
- }
-
- const std::unique_ptr<C2Worklet> &worklet = work->worklets.front();
-
- std::shared_ptr<C2Buffer> buffer;
- // NOTE: MediaCodec usage supposedly have only one output stream.
- if (worklet->output.buffers.size() > 1u) {
- ALOGI("[%s] onWorkDone: incorrect number of output buffers: %zu",
- mName, worklet->output.buffers.size());
- mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- return false;
- } else if (worklet->output.buffers.size() == 1u) {
- buffer = worklet->output.buffers[0];
- if (!buffer) {
- ALOGD("[%s] onWorkDone: nullptr found in buffers; ignored.", mName);
- }
- }
-
- while (!worklet->output.configUpdate.empty()) {
- std::unique_ptr<C2Param> param;
- worklet->output.configUpdate.back().swap(param);
- worklet->output.configUpdate.pop_back();
- switch (param->coreIndex().coreIndex()) {
- case C2PortReorderBufferDepthTuning::CORE_INDEX: {
- C2PortReorderBufferDepthTuning::output reorderDepth;
- if (reorderDepth.updateFrom(*param)) {
- mReorderStash.lock()->setDepth(reorderDepth.value);
- ALOGV("[%s] onWorkDone: updated reorder depth to %u",
- mName, reorderDepth.value);
- } else {
- ALOGD("[%s] onWorkDone: failed to read reorder depth", mName);
- }
- break;
- }
- case C2PortReorderKeySetting::CORE_INDEX: {
- C2PortReorderKeySetting::output reorderKey;
- if (reorderKey.updateFrom(*param)) {
- mReorderStash.lock()->setKey(reorderKey.value);
- ALOGV("[%s] onWorkDone: updated reorder key to %u",
- mName, reorderKey.value);
- } else {
- ALOGD("[%s] onWorkDone: failed to read reorder key", mName);
- }
- break;
- }
- default:
- ALOGV("[%s] onWorkDone: unrecognized config update (%08X)",
- mName, param->index());
- break;
- }
- }
-
- if (outputFormat != nullptr) {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- ALOGD("[%s] onWorkDone: output format changed to %s",
- mName, outputFormat->debugString().c_str());
- (*buffers)->setFormat(outputFormat);
-
- AString mediaType;
- if (outputFormat->findString(KEY_MIME, &mediaType)
- && mediaType == MIMETYPE_AUDIO_RAW) {
- int32_t channelCount;
- int32_t sampleRate;
- if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount)
- && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
- (*buffers)->updateSkipCutBuffer(sampleRate, channelCount);
- }
- }
- }
-
- int32_t flags = 0;
- if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) {
- flags |= MediaCodec::BUFFER_FLAG_EOS;
- ALOGV("[%s] onWorkDone: output EOS", mName);
- }
-
- sp<MediaCodecBuffer> outBuffer;
- size_t index;
-
- // WORKAROUND: adjust output timestamp based on client input timestamp and codec
- // input timestamp. Codec output timestamp (in the timestamp field) shall correspond to
- // the codec input timestamp, but client output timestamp should (reported in timeUs)
- // shall correspond to the client input timesamp (in customOrdinal). By using the
- // delta between the two, this allows for some timestamp deviation - e.g. if one input
- // produces multiple output.
- c2_cntr64_t timestamp =
- worklet->output.ordinal.timestamp + work->input.ordinal.customOrdinal
- - work->input.ordinal.timestamp;
- ALOGV("[%s] onWorkDone: input %lld, codec %lld => output %lld => %lld",
- mName,
- work->input.ordinal.customOrdinal.peekll(),
- work->input.ordinal.timestamp.peekll(),
- worklet->output.ordinal.timestamp.peekll(),
- timestamp.peekll());
-
- if (initData != nullptr) {
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- if ((*buffers)->registerCsd(initData, &index, &outBuffer) == OK) {
- outBuffer->meta()->setInt64("timeUs", timestamp.peek());
- outBuffer->meta()->setInt32("flags", MediaCodec::BUFFER_FLAG_CODECCONFIG);
- ALOGV("[%s] onWorkDone: csd index = %zu [%p]", mName, index, outBuffer.get());
-
- buffers.unlock();
- mCallback->onOutputBufferAvailable(index, outBuffer);
- buffers.lock();
- } else {
- ALOGD("[%s] onWorkDone: unable to register csd", mName);
- buffers.unlock();
- mCCodecCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
- buffers.lock();
- return false;
- }
- }
-
- if (!buffer && !flags) {
- ALOGV("[%s] onWorkDone: Not reporting output buffer (%lld)",
- mName, work->input.ordinal.frameIndex.peekull());
- return true;
- }
-
- if (buffer) {
- for (const std::shared_ptr<const C2Info> &info : buffer->info()) {
- // TODO: properly translate these to metadata
- switch (info->coreIndex().coreIndex()) {
- case C2StreamPictureTypeMaskInfo::CORE_INDEX:
- if (((C2StreamPictureTypeMaskInfo *)info.get())->value & C2PictureTypeKeyFrame) {
- flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME;
- }
- break;
- default:
- break;
- }
- }
- }
-
- {
- Mutexed<ReorderStash>::Locked reorder(mReorderStash);
- reorder->emplace(buffer, timestamp.peek(), flags, worklet->output.ordinal);
- if (flags & MediaCodec::BUFFER_FLAG_EOS) {
- // Flush reorder stash
- reorder->setDepth(0);
- }
- }
- sendOutputBuffers();
- return true;
-}
-
-void CCodecBufferChannel::sendOutputBuffers() {
- ReorderStash::Entry entry;
- sp<MediaCodecBuffer> outBuffer;
- size_t index;
-
- while (true) {
- {
- Mutexed<ReorderStash>::Locked reorder(mReorderStash);
- if (!reorder->hasPending()) {
- break;
- }
- if (!reorder->pop(&entry)) {
- break;
- }
- }
- Mutexed<std::unique_ptr<OutputBuffers>>::Locked buffers(mOutputBuffers);
- status_t err = (*buffers)->registerBuffer(entry.buffer, &index, &outBuffer);
- if (err != OK) {
- if (err != WOULD_BLOCK) {
- OutputBuffersArray *array = (OutputBuffersArray *)buffers->get();
- array->realloc(entry.buffer);
- mCCodecCallback->onOutputBuffersChanged();
- }
- buffers.unlock();
- ALOGV("[%s] sendOutputBuffers: unable to register output buffer", mName);
- mReorderStash.lock()->defer(entry);
- return;
- }
- buffers.unlock();
-
- outBuffer->meta()->setInt64("timeUs", entry.timestamp);
- outBuffer->meta()->setInt32("flags", entry.flags);
- ALOGV("[%s] sendOutputBuffers: out buffer index = %zu [%p] => %p + %zu",
- mName, index, outBuffer.get(), outBuffer->data(), outBuffer->size());
- mCallback->onOutputBufferAvailable(index, outBuffer);
- }
-}
-
-status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
- static std::atomic_uint32_t surfaceGeneration{0};
- uint32_t generation = (getpid() << 10) |
- ((surfaceGeneration.fetch_add(1, std::memory_order_relaxed) + 1)
- & ((1 << 10) - 1));
-
- sp<IGraphicBufferProducer> producer;
- if (newSurface) {
- newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
- newSurface->setMaxDequeuedBufferCount(kMinOutputBufferArraySize);
- producer = newSurface->getIGraphicBufferProducer();
- producer->setGenerationNumber(generation);
- } else {
- ALOGE("[%s] setting output surface to null", mName);
- return INVALID_OPERATION;
- }
-
- std::shared_ptr<Codec2Client::Configurable> outputPoolIntf;
- C2BlockPool::local_id_t outputPoolId;
- {
- Mutexed<BlockPools>::Locked pools(mBlockPools);
- outputPoolId = pools->outputPoolId;
- outputPoolIntf = pools->outputPoolIntf;
- }
-
- if (outputPoolIntf) {
- if (mComponent->setOutputSurface(
- outputPoolId,
- producer,
- generation) != C2_OK) {
- ALOGI("[%s] setSurface: component setOutputSurface failed", mName);
- return INVALID_OPERATION;
- }
- }
-
- {
- Mutexed<OutputSurface>::Locked output(mOutputSurface);
- output->surface = newSurface;
- output->generation = generation;
- }
-
- return OK;
-}
-
-void CCodecBufferChannel::setMetaMode(MetaMode mode) {
- mMetaMode = mode;
-}
-
-status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
- // C2_OK is always translated to OK.
- if (c2s == C2_OK) {
- return OK;
- }
-
- // Operation-dependent translation
- // TODO: Add as necessary
- switch (c2op) {
- case C2_OPERATION_Component_start:
- switch (c2s) {
- case C2_NO_MEMORY:
- return NO_MEMORY;
- default:
- return UNKNOWN_ERROR;
- }
- default:
- break;
- }
-
- // Backup operation-agnostic translation
- switch (c2s) {
- case C2_BAD_INDEX:
- return BAD_INDEX;
- case C2_BAD_VALUE:
- return BAD_VALUE;
- case C2_BLOCKING:
- return WOULD_BLOCK;
- case C2_DUPLICATE:
- return ALREADY_EXISTS;
- case C2_NO_INIT:
- return NO_INIT;
- case C2_NO_MEMORY:
- return NO_MEMORY;
- case C2_NOT_FOUND:
- return NAME_NOT_FOUND;
- case C2_TIMED_OUT:
- return TIMED_OUT;
- case C2_BAD_STATE:
- case C2_CANCELED:
- case C2_CANNOT_DO:
- case C2_CORRUPTED:
- case C2_OMITTED:
- case C2_REFUSED:
- return UNKNOWN_ERROR;
- default:
- return -static_cast<status_t>(c2s);
- }
-}
-
-} // namespace android
diff --git a/media/sfplugin/CCodecBufferChannel.h b/media/sfplugin/CCodecBufferChannel.h
deleted file mode 100644
index 1b3b605..0000000
--- a/media/sfplugin/CCodecBufferChannel.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright 2017, 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.
- */
-
-#ifndef CCODEC_BUFFER_CHANNEL_H_
-
-#define CCODEC_BUFFER_CHANNEL_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <C2Buffer.h>
-#include <C2Component.h>
-#include <Codec2Mapper.h>
-
-#include <codec2/hidl/client.h>
-#include <media/stagefright/bqhelper/GraphicBufferSource.h>
-#include <media/stagefright/codec2/1.0/InputSurface.h>
-#include <media/stagefright/foundation/Mutexed.h>
-#include <media/stagefright/CodecBase.h>
-
-#include "InputSurfaceWrapper.h"
-
-namespace android {
-
-class CCodecCallback {
-public:
- virtual ~CCodecCallback() = default;
- virtual void onError(status_t err, enum ActionCode actionCode) = 0;
- virtual void onOutputFramesRendered(int64_t mediaTimeUs, nsecs_t renderTimeNs) = 0;
- virtual void onWorkQueued(bool eos) = 0;
- virtual void onOutputBuffersChanged() = 0;
-};
-
-/**
- * BufferChannelBase implementation for CCodec.
- */
-class CCodecBufferChannel
- : public BufferChannelBase, public std::enable_shared_from_this<CCodecBufferChannel> {
-public:
- explicit CCodecBufferChannel(const std::shared_ptr<CCodecCallback> &callback);
- virtual ~CCodecBufferChannel();
-
- // BufferChannelBase interface
- virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
- virtual status_t queueSecureInputBuffer(
- const sp<MediaCodecBuffer> &buffer,
- bool secure,
- const uint8_t *key,
- const uint8_t *iv,
- CryptoPlugin::Mode mode,
- CryptoPlugin::Pattern pattern,
- const CryptoPlugin::SubSample *subSamples,
- size_t numSubSamples,
- AString *errorDetailMsg) override;
- virtual status_t renderOutputBuffer(
- const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) override;
- virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) override;
- virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
- virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) override;
-
- // Methods below are interface for CCodec to use.
-
- /**
- * Set the component object for buffer processing.
- */
- void setComponent(const std::shared_ptr<Codec2Client::Component> &component);
-
- /**
- * Set output graphic surface for rendering.
- */
- status_t setSurface(const sp<Surface> &surface);
-
- /**
- * Set GraphicBufferSource object from which the component extracts input
- * buffers.
- */
- status_t setInputSurface(const std::shared_ptr<InputSurfaceWrapper> &surface);
-
- /**
- * Signal EOS to input surface.
- */
- status_t signalEndOfInputStream();
-
- /**
- * Set parameters.
- */
- status_t setParameters(std::vector<std::unique_ptr<C2Param>> &params);
-
- /**
- * Start queueing buffers to the component. This object should never queue
- * buffers before this call has completed.
- */
- status_t start(const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat);
-
- /**
- * Request initial input buffers to be filled by client.
- */
- status_t requestInitialInputBuffers();
-
- /**
- * Stop queueing buffers to the component. This object should never queue
- * buffers after this call, until start() is called.
- */
- void stop();
-
- void flush(const std::list<std::unique_ptr<C2Work>> &flushedWork);
-
- /**
- * Notify input client about work done.
- *
- * @param workItems finished work item.
- * @param outputFormat new output format if it has changed, otherwise nullptr
- * @param initData new init data (CSD) if it has changed, otherwise nullptr
- * @param numDiscardedInputBuffers the number of input buffers that are
- * returned for the first time (not previously returned by
- * onInputBufferDone()).
- */
- void onWorkDone(
- std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
- const C2StreamInitDataInfo::output *initData,
- size_t numDiscardedInputBuffers);
-
- /**
- * Make an input buffer available for the client as it is no longer needed
- * by the codec.
- *
- * @param buffer The buffer that becomes unused.
- */
- void onInputBufferDone(const std::shared_ptr<C2Buffer>& buffer);
-
- enum MetaMode {
- MODE_NONE,
- MODE_ANW,
- };
-
- void setMetaMode(MetaMode mode);
-
- // Internal classes
- class Buffers;
- class InputBuffers;
- class OutputBuffers;
-
-private:
- class QueueGuard;
-
- /**
- * Special mutex-like object with the following properties:
- *
- * - At STOPPED state (initial, or after stop())
- * - QueueGuard object gets created at STOPPED state, and the client is
- * supposed to return immediately.
- * - At RUNNING state (after start())
- * - Each QueueGuard object
- */
- class QueueSync {
- public:
- /**
- * At construction the sync object is in STOPPED state.
- */
- inline QueueSync() {}
- ~QueueSync() = default;
-
- /**
- * Transition to RUNNING state when stopped. No-op if already in RUNNING
- * state.
- */
- void start();
-
- /**
- * At RUNNING state, wait until all QueueGuard object created during
- * RUNNING state are destroyed, and then transition to STOPPED state.
- * No-op if already in STOPPED state.
- */
- void stop();
-
- private:
- Mutex mGuardLock;
-
- struct Counter {
- inline Counter() : value(-1) {}
- int32_t value;
- Condition cond;
- };
- Mutexed<Counter> mCount;
-
- friend class CCodecBufferChannel::QueueGuard;
- };
-
- class QueueGuard {
- public:
- QueueGuard(QueueSync &sync);
- ~QueueGuard();
- inline bool isRunning() { return mRunning; }
-
- private:
- QueueSync &mSync;
- bool mRunning;
- };
-
- void feedInputBufferIfAvailable();
- void feedInputBufferIfAvailableInternal();
- status_t queueInputBufferInternal(const sp<MediaCodecBuffer> &buffer);
- bool handleWork(
- std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
- const C2StreamInitDataInfo::output *initData);
- void sendOutputBuffers();
-
- QueueSync mSync;
- sp<MemoryDealer> mDealer;
- sp<IMemory> mDecryptDestination;
- int32_t mHeapSeqNum;
-
- std::shared_ptr<Codec2Client::Component> mComponent;
- std::string mComponentName; ///< component name for debugging
- const char *mName; ///< C-string version of component name
- std::shared_ptr<CCodecCallback> mCCodecCallback;
- std::shared_ptr<C2BlockPool> mInputAllocator;
- QueueSync mQueueSync;
- std::vector<std::unique_ptr<C2Param>> mParamsToBeSet;
-
- Mutexed<std::unique_ptr<InputBuffers>> mInputBuffers;
- Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
- Mutexed<std::unique_ptr<OutputBuffers>> mOutputBuffers;
-
- std::atomic_uint64_t mFrameIndex;
- std::atomic_uint64_t mFirstValidFrameIndex;
-
- sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
-
- struct OutputSurface {
- sp<Surface> surface;
- uint32_t generation;
- };
- Mutexed<OutputSurface> mOutputSurface;
-
- struct BlockPools {
- C2Allocator::id_t inputAllocatorId;
- std::shared_ptr<C2BlockPool> inputPool;
- C2Allocator::id_t outputAllocatorId;
- C2BlockPool::local_id_t outputPoolId;
- std::shared_ptr<Codec2Client::Configurable> outputPoolIntf;
- };
- Mutexed<BlockPools> mBlockPools;
-
- std::shared_ptr<InputSurfaceWrapper> mInputSurface;
-
- MetaMode mMetaMode;
-
- // PipelineCapacity is used in the input buffer gating logic.
- //
- // There are three criteria that need to be met before
- // onInputBufferAvailable() is called:
- // 1. The number of input buffers that have been received by
- // CCodecBufferChannel but not returned via onWorkDone() or
- // onInputBufferDone() does not exceed a certain limit. (Let us call this
- // number the "input" capacity.)
- // 2. The number of work items that have been received by
- // CCodecBufferChannel whose outputs have not been returned from the
- // component (by calling onWorkDone()) does not exceed a certain limit.
- // (Let us call this the "component" capacity.)
- //
- // These three criteria guarantee that a new input buffer that arrives from
- // the invocation of onInputBufferAvailable() will not
- // 1. overload CCodecBufferChannel's input buffers;
- // 2. overload the component; or
- //
- struct PipelineCapacity {
- // The number of available input capacity.
- std::atomic_int input;
- // The number of available component capacity.
- std::atomic_int component;
-
- PipelineCapacity();
- // Set the values of #input and #component.
- void initialize(int newInput, int newComponent,
- const char* newName = "<UNKNOWN COMPONENT>",
- const char* callerTag = nullptr);
-
- // Return true and decrease #input and #component by one if
- // they are all greater than zero; return false otherwise.
- //
- // callerTag is used for logging only.
- //
- // allocate() is called by CCodecBufferChannel to check whether it can
- // receive another input buffer. If the return value is true,
- // onInputBufferAvailable() and onOutputBufferAvailable() can be called
- // afterwards.
- bool allocate(const char* callerTag = nullptr);
-
- // Increase #input and #component by one.
- //
- // callerTag is used for logging only.
- //
- // free() is called by CCodecBufferChannel after allocate() returns true
- // but onInputBufferAvailable() cannot be called for any reasons. It
- // essentially undoes an allocate() call.
- void free(const char* callerTag = nullptr);
-
- // Increase #input by @p numDiscardedInputBuffers.
- //
- // callerTag is used for logging only.
- //
- // freeInputSlots() is called by CCodecBufferChannel when onWorkDone()
- // or onInputBufferDone() is called. @p numDiscardedInputBuffers is
- // provided in onWorkDone(), and is 1 in onInputBufferDone().
- int freeInputSlots(size_t numDiscardedInputBuffers,
- const char* callerTag = nullptr);
-
- // Increase #component by one and return the updated value.
- //
- // callerTag is used for logging only.
- //
- // freeComponentSlot() is called by CCodecBufferChannel when
- // onWorkDone() is called.
- int freeComponentSlot(const char* callerTag = nullptr);
-
- private:
- // Component name. Used for logging.
- const char* mName;
- };
- PipelineCapacity mAvailablePipelineCapacity;
-
- class ReorderStash {
- public:
- struct Entry {
- inline Entry() : buffer(nullptr), timestamp(0), flags(0), ordinal({0, 0, 0}) {}
- inline Entry(
- const std::shared_ptr<C2Buffer> &b,
- int64_t t,
- int32_t f,
- const C2WorkOrdinalStruct &o)
- : buffer(b), timestamp(t), flags(f), ordinal(o) {}
- std::shared_ptr<C2Buffer> buffer;
- int64_t timestamp;
- int32_t flags;
- C2WorkOrdinalStruct ordinal;
- };
-
- ReorderStash();
-
- void clear();
- void setDepth(uint32_t depth);
- void setKey(C2Config::ordinal_key_t key);
- bool pop(Entry *entry);
- void emplace(
- const std::shared_ptr<C2Buffer> &buffer,
- int64_t timestamp,
- int32_t flags,
- const C2WorkOrdinalStruct &ordinal);
- void defer(const Entry &entry);
- bool hasPending() const;
-
- private:
- std::list<Entry> mPending;
- std::list<Entry> mStash;
- uint32_t mDepth;
- C2Config::ordinal_key_t mKey;
-
- bool less(const C2WorkOrdinalStruct &o1, const C2WorkOrdinalStruct &o2);
- };
- Mutexed<ReorderStash> mReorderStash;
-
- std::atomic_bool mInputMetEos;
-
- inline bool hasCryptoOrDescrambler() {
- return mCrypto != nullptr || mDescrambler != nullptr;
- }
-};
-
-// Conversion of a c2_status_t value to a status_t value may depend on the
-// operation that returns the c2_status_t value.
-enum c2_operation_t {
- C2_OPERATION_NONE,
- C2_OPERATION_Component_connectToOmxInputSurface,
- C2_OPERATION_Component_createBlockPool,
- C2_OPERATION_Component_destroyBlockPool,
- C2_OPERATION_Component_disconnectFromInputSurface,
- C2_OPERATION_Component_drain,
- C2_OPERATION_Component_flush,
- C2_OPERATION_Component_queue,
- C2_OPERATION_Component_release,
- C2_OPERATION_Component_reset,
- C2_OPERATION_Component_setOutputSurface,
- C2_OPERATION_Component_start,
- C2_OPERATION_Component_stop,
- C2_OPERATION_ComponentStore_copyBuffer,
- C2_OPERATION_ComponentStore_createComponent,
- C2_OPERATION_ComponentStore_createInputSurface,
- C2_OPERATION_ComponentStore_createInterface,
- C2_OPERATION_Configurable_config,
- C2_OPERATION_Configurable_query,
- C2_OPERATION_Configurable_querySupportedParams,
- C2_OPERATION_Configurable_querySupportedValues,
- C2_OPERATION_InputSurface_connectToComponent,
- C2_OPERATION_InputSurfaceConnection_disconnect,
-};
-
-status_t toStatusT(c2_status_t c2s, c2_operation_t c2op = C2_OPERATION_NONE);
-
-} // namespace android
-
-#endif // CCODEC_BUFFER_CHANNEL_H_
diff --git a/media/sfplugin/CCodecConfig.cpp b/media/sfplugin/CCodecConfig.cpp
deleted file mode 100644
index ef02e74..0000000
--- a/media/sfplugin/CCodecConfig.cpp
+++ /dev/null
@@ -1,1610 +0,0 @@
-/*
- * Copyright (C) 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 "CCodecConfig"
-#include <cutils/properties.h>
-#include <log/log.h>
-
-#include <C2Component.h>
-#include <C2Debug.h>
-#include <C2Param.h>
-#include <util/C2InterfaceHelper.h>
-
-#include <media/stagefright/MediaCodecConstants.h>
-
-#include "CCodecConfig.h"
-#include "Codec2Mapper.h"
-
-#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
-#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
-// names of properties that can be used to override the default DRC settings
-#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
-#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
-#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
-#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
-#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
-#define PROP_DRC_OVERRIDE_EFFECT "ro.aac_drc_effect_type"
-
-namespace android {
-
-// CCodecConfig
-
-namespace {
-
-/**
- * mapping between SDK and Codec 2.0 configurations.
- */
-struct ConfigMapper {
- /**
- * Value mapper (C2Value => C2Value)
- */
- typedef std::function<C2Value(C2Value)> Mapper;
-
- /// shorthand
- typedef CCodecConfig::Domain Domain;
-
- ConfigMapper(std::string mediaKey, C2String c2struct, C2String c2field)
- : mDomain(Domain::ALL), mMediaKey(mediaKey), mStruct(c2struct), mField(c2field) { }
-
- /// Limits this parameter to the given domain
- ConfigMapper &limitTo(uint32_t domain) {
- C2_CHECK(domain & Domain::GUARD_BIT);
- mDomain = Domain(mDomain & domain);
- return *this;
- }
-
- /// Adds SDK => Codec 2.0 mapper (should not be in the SDK format)
- ConfigMapper &withMapper(Mapper mapper) {
- C2_CHECK(!mMapper);
- C2_CHECK(!mReverse);
- mMapper = mapper;
- return *this;
- }
-
- /// Adds SDK <=> Codec 2.0 value mappers
- ConfigMapper &withMappers(Mapper mapper, Mapper reverse) {
- C2_CHECK(!mMapper);
- C2_CHECK(!mReverse);
- mMapper = mapper;
- mReverse = reverse;
- return *this;
- }
-
- /// Adds SDK <=> Codec 2.0 value mappers based on C2Mapper
- template<typename C2Type, typename SdkType=int32_t>
- ConfigMapper &withC2Mappers() {
- C2_CHECK(!mMapper);
- C2_CHECK(!mReverse);
- mMapper = [](C2Value v) -> C2Value {
- SdkType sdkValue;
- C2Type c2Value;
- if (v.get(&sdkValue) && C2Mapper::map(sdkValue, &c2Value)) {
- return c2Value;
- }
- return C2Value();
- };
- mReverse = [](C2Value v) -> C2Value {
- SdkType sdkValue;
- C2Type c2Value;
- using C2ValueType=typename _c2_reduce_enum_to_underlying_type<C2Type>::type;
- if (v.get((C2ValueType*)&c2Value) && C2Mapper::map(c2Value, &sdkValue)) {
- return sdkValue;
- }
- return C2Value();
- };
- return *this;
- }
-
- /// Maps from SDK values in an AMessage to a suitable C2Value.
- C2Value mapFromMessage(const AMessage::ItemData &item) const {
- C2Value value;
- int32_t int32Value;
- int64_t int64Value;
- float floatValue;
- double doubleValue;
- if (item.find(&int32Value)) {
- value = int32Value;
- } else if (item.find(&int64Value)) {
- value = int64Value;
- } else if (item.find(&floatValue)) {
- value = floatValue;
- } else if (item.find(&doubleValue)) {
- value = (float)doubleValue;
- }
- if (value.type() != C2Value::NO_INIT && mMapper) {
- value = mMapper(value);
- }
- return value;
- }
-
- /// Maps from a C2Value to an SDK value in an AMessage.
- AMessage::ItemData mapToMessage(C2Value value) const {
- AMessage::ItemData item;
- int32_t int32Value;
- uint32_t uint32Value;
- int64_t int64Value;
- uint64_t uint64Value;
- float floatValue;
- if (value.type() != C2Value::NO_INIT && mReverse) {
- value = mReverse(value);
- }
- if (value.get(&int32Value)) {
- item.set(int32Value);
- } else if (value.get(&uint32Value) && uint32Value <= uint32_t(INT32_MAX)) {
- // SDK does not support unsigned values
- item.set((int32_t)uint32Value);
- } else if (value.get(&int64Value)) {
- item.set(int64Value);
- } else if (value.get(&uint64Value) && uint64Value <= uint64_t(INT64_MAX)) {
- // SDK does not support unsigned values
- item.set((int64_t)uint64Value);
- } else if (value.get(&floatValue)) {
- item.set(floatValue);
- }
- return item;
- }
-
- Domain domain() const { return mDomain; }
- std::string mediaKey() const { return mMediaKey; }
- std::string path() const { return mField.size() ? mStruct + '.' + mField : mStruct; }
- Mapper mapper() const { return mMapper; }
- Mapper reverse() const { return mReverse; }
-
-private:
- Domain mDomain; ///< parameter domain (mask) containing port, kind and config domains
- std::string mMediaKey; ///< SDK key
- C2String mStruct; ///< Codec 2.0 struct name
- C2String mField; ///< Codec 2.0 field name
- Mapper mMapper; ///< optional SDK => Codec 2.0 value mapper
- Mapper mReverse; ///< optional Codec 2.0 => SDK value mapper
-};
-
-template <typename PORT, typename STREAM>
-AString QueryMediaTypeImpl(
- const std::shared_ptr<Codec2Client::Component> &component) {
- AString mediaType;
- std::vector<std::unique_ptr<C2Param>> queried;
- c2_status_t c2err = component->query(
- {}, { PORT::PARAM_TYPE, STREAM::PARAM_TYPE }, C2_DONT_BLOCK, &queried);
- if (c2err != C2_OK && queried.size() == 0) {
- ALOGD("Query media type failed => %s", asString(c2err));
- } else {
- PORT *portMediaType =
- PORT::From(queried[0].get());
- if (portMediaType) {
- mediaType = AString(
- portMediaType->m.value,
- strnlen(portMediaType->m.value, portMediaType->flexCount()));
- } else {
- STREAM *streamMediaType = STREAM::From(queried[0].get());
- if (streamMediaType) {
- mediaType = AString(
- streamMediaType->m.value,
- strnlen(streamMediaType->m.value, streamMediaType->flexCount()));
- }
- }
- ALOGD("read media type: %s", mediaType.c_str());
- }
- return mediaType;
-}
-
-AString QueryMediaType(
- bool input, const std::shared_ptr<Codec2Client::Component> &component) {
- typedef C2PortMediaTypeSetting P;
- typedef C2StreamMediaTypeSetting S;
- if (input) {
- return QueryMediaTypeImpl<P::input, S::input>(component);
- } else {
- return QueryMediaTypeImpl<P::output, S::output>(component);
- }
-}
-
-} // namespace
-
-/**
- * Set of standard parameters used by CCodec that are exposed to MediaCodec.
- */
-struct StandardParams {
- typedef CCodecConfig::Domain Domain;
-
- // standard (MediaCodec) params are keyed by media format key
- typedef std::string SdkKey;
-
- /// used to return reference to no config mappers in getConfigMappersForSdkKey
- static const std::vector<ConfigMapper> NO_MAPPERS;
-
- /// Returns Codec 2.0 equivalent parameters for an SDK format key.
- const std::vector<ConfigMapper> &getConfigMappersForSdkKey(std::string key) const {
- auto it = mConfigMappers.find(key);
- if (it == mConfigMappers.end()) {
- ALOGD("no c2 equivalents for %s", key.c_str());
- return NO_MAPPERS;
- }
- ALOGV("found %zu eqs for %s", it->second.size(), key.c_str());
- return it->second;
- }
-
- /**
- * Adds a SDK <=> Codec 2.0 parameter mapping. Multiple Codec 2.0 parameters may map to a
- * single SDK key, in which case they shall be ordered from least authoritative to most
- * authoritative. When constructing SDK formats, the last mapped Codec 2.0 parameter that
- * is supported by the component will determine the exposed value. (TODO: perhaps restrict this
- * by domain.)
- */
- void add(const ConfigMapper &cm) {
- auto it = mConfigMappers.find(cm.mediaKey());
- ALOGV("%c%c%c%c %c%c%c %04x %9s %s => %s",
- ((cm.domain() & Domain::IS_INPUT) ? 'I' : ' '),
- ((cm.domain() & Domain::IS_OUTPUT) ? 'O' : ' '),
- ((cm.domain() & Domain::IS_CODED) ? 'C' : ' '),
- ((cm.domain() & Domain::IS_RAW) ? 'R' : ' '),
- ((cm.domain() & Domain::IS_CONFIG) ? 'c' : ' '),
- ((cm.domain() & Domain::IS_PARAM) ? 'p' : ' '),
- ((cm.domain() & Domain::IS_READ) ? 'r' : ' '),
- cm.domain(),
- it == mConfigMappers.end() ? "adding" : "extending",
- cm.mediaKey().c_str(), cm.path().c_str());
- if (it == mConfigMappers.end()) {
- std::vector<ConfigMapper> eqs = { cm };
- mConfigMappers.emplace(cm.mediaKey(), eqs);
- } else {
- it->second.push_back(cm);
- }
- }
-
- /**
- * Returns all paths for a specific domain.
- *
- * \param any maximum domain mask. Returned parameters must match at least one of the domains
- * in the mask.
- * \param all minimum domain mask. Returned parameters must match all of the domains in the
- * mask. This is restricted to the bits of the maximum mask.
- */
- std::vector<std::string> getPathsForDomain(
- Domain any, Domain all = Domain::ALL) const {
- std::vector<std::string> res;
- for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mConfigMappers) {
- for (const ConfigMapper &cm : el.second) {
- ALOGV("filtering %s %x %x %x %x", cm.path().c_str(), cm.domain(), any,
- (cm.domain() & any), (cm.domain() & any & all));
- if ((cm.domain() & any) && ((cm.domain() & any & all) == (any & all))) {
- res.push_back(cm.path());
- }
- }
- }
- return res;
- }
-
- /**
- * Returns SDK <=> Codec 2.0 mappings.
- *
- * TODO: replace these with better methods as this exposes the inner structure.
- */
- const std::map<SdkKey, std::vector<ConfigMapper>> getKeys() const {
- return mConfigMappers;
- }
-
-private:
- std::map<SdkKey, std::vector<ConfigMapper>> mConfigMappers;
-};
-
-const std::vector<ConfigMapper> StandardParams::NO_MAPPERS;
-
-
-CCodecConfig::CCodecConfig()
- : mInputFormat(new AMessage),
- mOutputFormat(new AMessage),
- mUsingSurface(false) { }
-
-void CCodecConfig::initializeStandardParams() {
- typedef Domain D;
- mStandardParams = std::make_shared<StandardParams>();
- std::function<void(const ConfigMapper &)> add =
- [params = mStandardParams](const ConfigMapper &cm) {
- params->add(cm);
- };
- std::function<void(const ConfigMapper &)> deprecated = add;
-
- // allow int32 or float SDK values and represent them as float
- ConfigMapper::Mapper makeFloat = [](C2Value v) -> C2Value {
- // convert from i32 to float
- int32_t i32Value;
- float fpValue;
- if (v.get(&i32Value)) {
- return (float)i32Value;
- } else if (v.get(&fpValue)) {
- return fpValue;
- }
- return C2Value();
- };
-
- ConfigMapper::Mapper negate = [](C2Value v) -> C2Value {
- int32_t value;
- if (v.get(&value)) {
- return -value;
- }
- return C2Value();
- };
-
- add(ConfigMapper(KEY_MIME, C2_PARAMKEY_INPUT_MEDIA_TYPE, "value")
- .limitTo(D::INPUT & D::READ));
- add(ConfigMapper(KEY_MIME, C2_PARAMKEY_OUTPUT_MEDIA_TYPE, "value")
- .limitTo(D::OUTPUT & D::READ));
-
- add(ConfigMapper(KEY_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
- .limitTo(D::ENCODER & D::OUTPUT));
- // we also need to put the bitrate in the max bitrate field
- add(ConfigMapper(KEY_MAX_BIT_RATE, C2_PARAMKEY_BITRATE, "value")
- .limitTo(D::ENCODER & D::READ & D::OUTPUT));
- add(ConfigMapper(PARAMETER_KEY_VIDEO_BITRATE, C2_PARAMKEY_BITRATE, "value")
- .limitTo(D::ENCODER & D::VIDEO & D::PARAM));
- add(ConfigMapper(KEY_BITRATE_MODE, C2_PARAMKEY_BITRATE_MODE, "value")
- .limitTo(D::ENCODER & D::CODED)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- C2Config::bitrate_mode_t mode;
- if (v.get(&value) && C2Mapper::map(value, &mode)) {
- return mode;
- }
- return C2Value();
- }));
- // remove when codecs switch to PARAMKEY and new modes
- deprecated(ConfigMapper(KEY_BITRATE_MODE, "coded.bitrate-mode", "value")
- .limitTo(D::ENCODER));
- add(ConfigMapper(KEY_FRAME_RATE, C2_PARAMKEY_FRAME_RATE, "value")
- .limitTo(D::VIDEO)
- .withMappers(makeFloat, [](C2Value v) -> C2Value {
- // read back always as int
- float value;
- if (v.get(&value)) {
- return (int32_t)value;
- }
- return C2Value();
- }));
-
- add(ConfigMapper(KEY_MAX_INPUT_SIZE, C2_PARAMKEY_INPUT_MAX_BUFFER_SIZE, "value")
- .limitTo(D::INPUT));
- // remove when codecs switch to PARAMKEY
- deprecated(ConfigMapper(KEY_MAX_INPUT_SIZE, "coded.max-frame-size", "value")
- .limitTo(D::INPUT));
-
- // Rotation
- // Note: SDK rotation is clock-wise, while C2 rotation is counter-clock-wise
- add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_VUI_ROTATION, "value")
- .limitTo(D::VIDEO & D::CODED)
- .withMappers(negate, negate));
- add(ConfigMapper(KEY_ROTATION, C2_PARAMKEY_ROTATION, "value")
- .limitTo(D::VIDEO & D::RAW)
- .withMappers(negate, negate));
-
- // android 'video-scaling'
- add(ConfigMapper("android._video-scaling", C2_PARAMKEY_SURFACE_SCALING_MODE, "value")
- .limitTo(D::VIDEO & D::DECODER & D::RAW));
-
- // Color Aspects
- //
- // configure default for decoders
- add(ConfigMapper(KEY_COLOR_RANGE, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS, "range")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::CODED & (D::CONFIG | D::PARAM))
- .withC2Mappers<C2Color::range_t>());
- add(ConfigMapper(KEY_COLOR_TRANSFER, C2_PARAMKEY_DEFAULT_COLOR_ASPECTS, "transfer")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::CODED & (D::CONFIG | D::PARAM))
- .withC2Mappers<C2Color::transfer_t>());
- add(ConfigMapper("color-primaries", C2_PARAMKEY_DEFAULT_COLOR_ASPECTS, "primaries")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::CODED & (D::CONFIG | D::PARAM)));
- add(ConfigMapper("color-matrix", C2_PARAMKEY_DEFAULT_COLOR_ASPECTS, "matrix")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::CODED & (D::CONFIG | D::PARAM)));
-
- // read back final for decoder output (also, configure final aspects as well. This should be
- // overwritten based on coded/default values if component supports color aspects, but is used
- // as final values if component does not support aspects at all)
- add(ConfigMapper(KEY_COLOR_RANGE, C2_PARAMKEY_COLOR_ASPECTS, "range")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::RAW)
- .withC2Mappers<C2Color::range_t>());
- add(ConfigMapper(KEY_COLOR_TRANSFER, C2_PARAMKEY_COLOR_ASPECTS, "transfer")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::RAW)
- .withC2Mappers<C2Color::transfer_t>());
- add(ConfigMapper("color-primaries", C2_PARAMKEY_COLOR_ASPECTS, "primaries")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::RAW));
- add(ConfigMapper("color-matrix", C2_PARAMKEY_COLOR_ASPECTS, "matrix")
- .limitTo((D::VIDEO | D::IMAGE) & D::DECODER & D::RAW));
-
- // configure source aspects for encoders and read them back on the coded(!) port.
- // This is to ensure muxing the desired aspects into the container.
- add(ConfigMapper(KEY_COLOR_RANGE, C2_PARAMKEY_COLOR_ASPECTS, "range")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::CODED)
- .withC2Mappers<C2Color::range_t>());
- add(ConfigMapper(KEY_COLOR_TRANSFER, C2_PARAMKEY_COLOR_ASPECTS, "transfer")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::CODED)
- .withC2Mappers<C2Color::transfer_t>());
- add(ConfigMapper("color-primaries", C2_PARAMKEY_COLOR_ASPECTS, "primaries")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::CODED));
- add(ConfigMapper("color-matrix", C2_PARAMKEY_COLOR_ASPECTS, "matrix")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::CODED));
-
- // read back coded aspects for encoders (on the raw port), but also configure
- // desired aspects here.
- add(ConfigMapper(KEY_COLOR_RANGE, C2_PARAMKEY_VUI_COLOR_ASPECTS, "range")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::RAW)
- .withC2Mappers<C2Color::range_t>());
- add(ConfigMapper(KEY_COLOR_TRANSFER, C2_PARAMKEY_VUI_COLOR_ASPECTS, "transfer")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::RAW)
- .withC2Mappers<C2Color::transfer_t>());
- add(ConfigMapper("color-primaries", C2_PARAMKEY_VUI_COLOR_ASPECTS, "primaries")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::RAW));
- add(ConfigMapper("color-matrix", C2_PARAMKEY_VUI_COLOR_ASPECTS, "matrix")
- .limitTo((D::VIDEO | D::IMAGE) & D::ENCODER & D::RAW));
-
- // Dataspace
- add(ConfigMapper("android._dataspace", C2_PARAMKEY_DATA_SPACE, "value")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
-
- // HDR
- add(ConfigMapper("smpte2086.red.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.x")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.red.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.red.y")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.green.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.x")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.green.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.green.y")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.blue.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.x")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.blue.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.blue.y")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.white.x", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.x")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.white.y", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.white.y")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.max-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.max-luminance")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("smpte2086.min-luminance", C2_PARAMKEY_HDR_STATIC_INFO, "mastering.min-luminance")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("cta861.max-cll", C2_PARAMKEY_HDR_STATIC_INFO, "max-cll")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper("cta861.max-fall", C2_PARAMKEY_HDR_STATIC_INFO, "max-fall")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
-
- add(ConfigMapper(std::string(KEY_FEATURE_) + FEATURE_SecurePlayback,
- C2_PARAMKEY_SECURE_MODE, "value"));
-
- add(ConfigMapper("prepend-sps-pps-to-idr-frames",
- C2_PARAMKEY_PREPEND_HEADER_MODE, "value")
- .limitTo(D::ENCODER & D::VIDEO)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (v.get(&value) && value) {
- return C2Value(C2Config::PREPEND_HEADER_TO_ALL_SYNC);
- } else {
- return C2Value(C2Config::PREPEND_HEADER_TO_NONE);
- }
- }));
- // remove when codecs switch to PARAMKEY
- deprecated(ConfigMapper("prepend-sps-pps-to-idr-frames",
- "coding.add-csd-to-sync-frames", "value")
- .limitTo(D::ENCODER & D::VIDEO));
- // convert to timestamp base
- add(ConfigMapper(KEY_I_FRAME_INTERVAL, C2_PARAMKEY_SYNC_FRAME_INTERVAL, "value")
- .withMapper([](C2Value v) -> C2Value {
- // convert from i32 to float
- int32_t i32Value;
- float fpValue;
- if (v.get(&i32Value)) {
- return int64_t(1000000) * i32Value;
- } else if (v.get(&fpValue)) {
- return int64_t(c2_min(1000000 * fpValue + 0.5, (double)INT64_MAX));
- }
- return C2Value();
- }));
- // remove when codecs switch to proper coding.gop (add support for calculating gop)
- deprecated(ConfigMapper("i-frame-period", "coding.gop", "intra-period")
- .limitTo(D::ENCODER & D::VIDEO));
- add(ConfigMapper(KEY_INTRA_REFRESH_PERIOD, C2_PARAMKEY_INTRA_REFRESH, "period")
- .limitTo(D::VIDEO & D::ENCODER)
- .withMappers(makeFloat, [](C2Value v) -> C2Value {
- // read back always as int
- float value;
- if (v.get(&value)) {
- return (int32_t)value;
- }
- return C2Value();
- }));
- add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value"));
- deprecated(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
- "coding.request-sync", "value")
- .limitTo(D::PARAM & D::ENCODER)
- .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
- add(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
- C2_PARAMKEY_REQUEST_SYNC_FRAME, "value")
- .limitTo(D::PARAM & D::ENCODER)
- .withMapper([](C2Value) -> C2Value { return uint32_t(1); }));
-
- add(ConfigMapper(KEY_OPERATING_RATE, C2_PARAMKEY_OPERATING_RATE, "value")
- .limitTo(D::PARAM | D::CONFIG) // write-only
- .withMapper(makeFloat));
- // C2 priorities are inverted
- add(ConfigMapper(KEY_PRIORITY, C2_PARAMKEY_PRIORITY, "value")
- .withMappers(negate, negate));
- // remove when codecs switch to PARAMKEY
- deprecated(ConfigMapper(KEY_OPERATING_RATE, "ctrl.operating-rate", "value")
- .withMapper(makeFloat));
- deprecated(ConfigMapper(KEY_PRIORITY, "ctrl.priority", "value"));
-
- add(ConfigMapper(KEY_WIDTH, C2_PARAMKEY_PICTURE_SIZE, "width")
- .limitTo(D::VIDEO | D::IMAGE));
- add(ConfigMapper(KEY_HEIGHT, C2_PARAMKEY_PICTURE_SIZE, "height")
- .limitTo(D::VIDEO | D::IMAGE));
-
- add(ConfigMapper("crop-left", C2_PARAMKEY_CROP_RECT, "left")
- .limitTo(D::VIDEO | D::IMAGE));
- add(ConfigMapper("crop-top", C2_PARAMKEY_CROP_RECT, "top")
- .limitTo(D::VIDEO | D::IMAGE));
- add(ConfigMapper("crop-width", C2_PARAMKEY_CROP_RECT, "width")
- .limitTo(D::VIDEO | D::IMAGE));
- add(ConfigMapper("crop-height", C2_PARAMKEY_CROP_RECT, "height")
- .limitTo(D::VIDEO | D::IMAGE));
-
- add(ConfigMapper(KEY_MAX_WIDTH, C2_PARAMKEY_MAX_PICTURE_SIZE, "width")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
- add(ConfigMapper(KEY_MAX_HEIGHT, C2_PARAMKEY_MAX_PICTURE_SIZE, "height")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW));
-
- add(ConfigMapper("csd-0", C2_PARAMKEY_INIT_DATA, "value")
- .limitTo(D::OUTPUT & D::READ));
-
- add(ConfigMapper(KEY_HDR10_PLUS_INFO, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO, "value")
- .limitTo(D::VIDEO & D::PARAM & D::INPUT));
-
- add(ConfigMapper(KEY_HDR10_PLUS_INFO, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO, "value")
- .limitTo(D::VIDEO & D::OUTPUT));
-
- add(ConfigMapper(C2_PARAMKEY_TEMPORAL_LAYERING, C2_PARAMKEY_TEMPORAL_LAYERING, "")
- .limitTo(D::ENCODER & D::VIDEO & D::OUTPUT));
-
- // Pixel Format (use local key for actual pixel format as we don't distinguish between
- // SDK layouts for flexible format and we need the actual SDK color format in the media format)
- add(ConfigMapper("android._color-format", C2_PARAMKEY_PIXEL_FORMAT, "value")
- .limitTo((D::VIDEO | D::IMAGE) & D::RAW)
- .withMappers([](C2Value v) -> C2Value {
- int32_t value;
- if (v.get(&value)) {
- switch (value) {
- case COLOR_FormatSurface:
- return (uint32_t)HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
- case COLOR_FormatYUV420Flexible:
- return (uint32_t)HAL_PIXEL_FORMAT_YCBCR_420_888;
- case COLOR_FormatYUV420Planar:
- case COLOR_FormatYUV420SemiPlanar:
- case COLOR_FormatYUV420PackedPlanar:
- case COLOR_FormatYUV420PackedSemiPlanar:
- return (uint32_t)HAL_PIXEL_FORMAT_YV12;
- default:
- // TODO: support some sort of passthrough
- break;
- }
- }
- return C2Value();
- }, [](C2Value v) -> C2Value {
- uint32_t value;
- if (v.get(&value)) {
- switch (value) {
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
- return COLOR_FormatSurface;
- case HAL_PIXEL_FORMAT_YV12:
- case HAL_PIXEL_FORMAT_YCBCR_420_888:
- return COLOR_FormatYUV420Flexible;
- default:
- // TODO: support some sort of passthrough
- break;
- }
- }
- return C2Value();
- }));
-
- add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CHANNEL_COUNT, "value")
- .limitTo(D::AUDIO)); // read back to both formats
- add(ConfigMapper(KEY_CHANNEL_COUNT, C2_PARAMKEY_CODED_CHANNEL_COUNT, "value")
- .limitTo(D::AUDIO & D::CODED));
-
- add(ConfigMapper(KEY_SAMPLE_RATE, C2_PARAMKEY_SAMPLE_RATE, "value")
- .limitTo(D::AUDIO)); // read back to both port formats
- add(ConfigMapper(KEY_SAMPLE_RATE, C2_PARAMKEY_CODED_SAMPLE_RATE, "value")
- .limitTo(D::AUDIO & D::CODED));
-
- add(ConfigMapper(KEY_PCM_ENCODING, C2_PARAMKEY_PCM_ENCODING, "value")
- .limitTo(D::AUDIO)
- .withMappers([](C2Value v) -> C2Value {
- int32_t value;
- C2Config::pcm_encoding_t to;
- if (v.get(&value) && C2Mapper::map(value, &to)) {
- return to;
- }
- return C2Value();
- }, [](C2Value v) -> C2Value {
- C2Config::pcm_encoding_t value;
- int32_t to;
- using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(value)>::type;
- if (v.get((C2ValueType*)&value) && C2Mapper::map(value, &to)) {
- return to;
- }
- return C2Value();
- }));
-
- add(ConfigMapper(KEY_IS_ADTS, C2_PARAMKEY_AAC_PACKAGING, "value")
- .limitTo(D::AUDIO & D::CODED)
- .withMappers([](C2Value v) -> C2Value {
- int32_t value;
- if (v.get(&value) && value) {
- return C2Config::AAC_PACKAGING_ADTS;
- }
- return C2Value();
- }, [](C2Value v) -> C2Value {
- uint32_t value;
- if (v.get(&value) && value == C2Config::AAC_PACKAGING_ADTS) {
- return (int32_t)1;
- }
- return C2Value();
- }));
-
- std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
- C2Mapper::GetProfileLevelMapper(mCodingMediaType);
-
- add(ConfigMapper(KEY_PROFILE, C2_PARAMKEY_PROFILE_LEVEL, "profile")
- .limitTo(D::CODED)
- .withMappers([mapper](C2Value v) -> C2Value {
- C2Config::profile_t c2 = PROFILE_UNUSED;
- int32_t sdk;
- if (mapper && v.get(&sdk) && mapper->mapProfile(sdk, &c2)) {
- return c2;
- }
- return PROFILE_UNUSED;
- }, [mapper](C2Value v) -> C2Value {
- C2Config::profile_t c2;
- int32_t sdk;
- using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
- if (mapper && v.get((C2ValueType*)&c2) && mapper->mapProfile(c2, &sdk)) {
- return sdk;
- }
- return C2Value();
- }));
-
- add(ConfigMapper(KEY_LEVEL, C2_PARAMKEY_PROFILE_LEVEL, "level")
- .limitTo(D::CODED)
- .withMappers([mapper](C2Value v) -> C2Value {
- C2Config::level_t c2 = LEVEL_UNUSED;
- int32_t sdk;
- if (mapper && v.get(&sdk) && mapper->mapLevel(sdk, &c2)) {
- return c2;
- }
- return LEVEL_UNUSED;
- }, [mapper](C2Value v) -> C2Value {
- C2Config::level_t c2;
- int32_t sdk;
- using C2ValueType=typename _c2_reduce_enum_to_underlying_type<decltype(c2)>::type;
- if (mapper && v.get((C2ValueType*)&c2) && mapper->mapLevel(c2, &sdk)) {
- return sdk;
- }
- return C2Value();
- }));
-
- // convert to dBFS and add default
- add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
- .limitTo(D::AUDIO & D::DECODER)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < 0) {
- value = property_get_int32(PROP_DRC_OVERRIDE_REF_LEVEL, DRC_DEFAULT_MOBILE_REF_LEVEL);
- }
- return float(-0.25 * c2_min(value, 127));
- }));
-
- // convert to 0-1 (%) and add default
- add(ConfigMapper(KEY_AAC_DRC_ATTENUATION_FACTOR, C2_PARAMKEY_DRC_ATTENUATION_FACTOR, "value")
- .limitTo(D::AUDIO & D::DECODER)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < 0) {
- value = property_get_int32(PROP_DRC_OVERRIDE_CUT, DRC_DEFAULT_MOBILE_DRC_CUT);
- }
- return float(c2_min(value, 127) / 127.);
- }));
-
- // convert to 0-1 (%) and add default
- add(ConfigMapper(KEY_AAC_DRC_BOOST_FACTOR, C2_PARAMKEY_DRC_BOOST_FACTOR, "value")
- .limitTo(D::AUDIO & D::DECODER)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < 0) {
- value = property_get_int32(PROP_DRC_OVERRIDE_BOOST, DRC_DEFAULT_MOBILE_DRC_BOOST);
- }
- return float(c2_min(value, 127) / 127.);
- }));
-
- // convert to compression type and add default
- add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
- .limitTo(D::AUDIO & D::DECODER)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < 0) {
- value = property_get_int32(PROP_DRC_OVERRIDE_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
- }
- return value == 1 ? C2Config::DRC_COMPRESSION_HEAVY : C2Config::DRC_COMPRESSION_LIGHT;
- }));
-
- // convert to dBFS and add default
- add(ConfigMapper(KEY_AAC_ENCODED_TARGET_LEVEL, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL, "value")
- .limitTo(D::AUDIO & D::DECODER)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < 0) {
- value = property_get_int32(PROP_DRC_OVERRIDE_ENC_LEVEL, DRC_DEFAULT_MOBILE_ENC_LEVEL);
- }
- return float(-0.25 * c2_min(value, 127));
- }));
-
- // convert to effect type (these map to SDK values) and add default
- add(ConfigMapper(KEY_AAC_DRC_EFFECT_TYPE, C2_PARAMKEY_DRC_EFFECT_TYPE, "value")
- .limitTo(D::AUDIO & D::DECODER)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < -1 || value > 8) {
- value = property_get_int32(PROP_DRC_OVERRIDE_EFFECT, DRC_DEFAULT_MOBILE_DRC_EFFECT);
- // ensure value is within range
- if (value < -1 || value > 8) {
- value = DRC_DEFAULT_MOBILE_DRC_EFFECT;
- }
- }
- return value;
- }));
-
- add(ConfigMapper(KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
- .limitTo(D::AUDIO));
-
- add(ConfigMapper(KEY_AAC_SBR_MODE, C2_PARAMKEY_AAC_SBR_MODE, "value")
- .limitTo(D::AUDIO & D::ENCODER & D::CONFIG)
- .withMapper([](C2Value v) -> C2Value {
- int32_t value;
- if (!v.get(&value) || value < 0) {
- return C2Config::AAC_SBR_AUTO;
- }
- switch (value) {
- case 0: return C2Config::AAC_SBR_OFF;
- case 1: return C2Config::AAC_SBR_SINGLE_RATE;
- case 2: return C2Config::AAC_SBR_DUAL_RATE;
- default: return C2Config::AAC_SBR_AUTO + 1; // invalid value
- }
- }));
-
- add(ConfigMapper(KEY_QUALITY, C2_PARAMKEY_QUALITY, "value"));
- add(ConfigMapper(KEY_FLAC_COMPRESSION_LEVEL, C2_PARAMKEY_COMPLEXITY, "value")
- .limitTo(D::AUDIO & D::ENCODER));
- add(ConfigMapper("complexity", C2_PARAMKEY_COMPLEXITY, "value")
- .limitTo(D::ENCODER));
-
- add(ConfigMapper(KEY_GRID_COLUMNS, C2_PARAMKEY_TILE_LAYOUT, "columns")
- .limitTo(D::IMAGE));
- add(ConfigMapper(KEY_GRID_ROWS, C2_PARAMKEY_TILE_LAYOUT, "rows")
- .limitTo(D::IMAGE));
- add(ConfigMapper(KEY_TILE_WIDTH, C2_PARAMKEY_TILE_LAYOUT, "tile.width")
- .limitTo(D::IMAGE));
- add(ConfigMapper(KEY_TILE_HEIGHT, C2_PARAMKEY_TILE_LAYOUT, "tile.height")
- .limitTo(D::IMAGE));
-
- add(ConfigMapper(KEY_LATENCY, C2_PARAMKEY_PIPELINE_DELAY_REQUEST, "value")
- .limitTo(D::VIDEO & D::ENCODER));
-
- add(ConfigMapper(C2_PARAMKEY_INPUT_TIME_STRETCH, C2_PARAMKEY_INPUT_TIME_STRETCH, "value"));
-
- /* still to do
- constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
-
- not yet used by MediaCodec, but defined as MediaFormat
- KEY_AUDIO_SESSION_ID // we use "audio-hw-sync"
- KEY_OUTPUT_REORDER_DEPTH
- */
-}
-
-status_t CCodecConfig::initialize(
- const std::shared_ptr<Codec2Client> &client,
- const std::shared_ptr<Codec2Client::Component> &component) {
- C2ComponentDomainSetting domain(C2Component::DOMAIN_OTHER);
- C2ComponentKindSetting kind(C2Component::KIND_OTHER);
-
- std::vector<std::unique_ptr<C2Param>> queried;
- c2_status_t c2err = component->query({ &domain, &kind }, {}, C2_DONT_BLOCK, &queried);
- if (c2err != C2_OK) {
- ALOGD("Query domain & kind failed => %s", asString(c2err));
- // TEMP: determine kind from component name
- if (kind.value == C2Component::KIND_OTHER) {
- if (component->getName().find("encoder") != std::string::npos) {
- kind.value = C2Component::KIND_ENCODER;
- } else if (component->getName().find("decoder") != std::string::npos) {
- kind.value = C2Component::KIND_DECODER;
- }
- }
-
- // TEMP: determine domain from media type (port (preferred) or stream #0)
- if (domain.value == C2Component::DOMAIN_OTHER) {
- AString mediaType = QueryMediaType(true /* input */, component);
- if (mediaType.startsWith("audio/")) {
- domain.value = C2Component::DOMAIN_AUDIO;
- } else if (mediaType.startsWith("video/")) {
- domain.value = C2Component::DOMAIN_VIDEO;
- } else if (mediaType.startsWith("image/")) {
- domain.value = C2Component::DOMAIN_IMAGE;
- }
- }
- }
-
- mDomain = (domain.value == C2Component::DOMAIN_VIDEO ? Domain::IS_VIDEO :
- domain.value == C2Component::DOMAIN_IMAGE ? Domain::IS_IMAGE :
- domain.value == C2Component::DOMAIN_AUDIO ? Domain::IS_AUDIO : Domain::OTHER_DOMAIN)
- | (kind.value == C2Component::KIND_DECODER ? Domain::IS_DECODER :
- kind.value == C2Component::KIND_ENCODER ? Domain::IS_ENCODER : Domain::OTHER_KIND);
-
- mInputDomain = Domain(((mDomain & IS_DECODER) ? IS_CODED : IS_RAW) | IS_INPUT);
- mOutputDomain = Domain(((mDomain & IS_ENCODER) ? IS_CODED : IS_RAW) | IS_OUTPUT);
-
- ALOGV("domain is %#x (%u %u)", mDomain, domain.value, kind.value);
-
- std::vector<C2Param::Index> paramIndices;
- switch (kind.value) {
- case C2Component::KIND_DECODER:
- mCodingMediaType = QueryMediaType(true /* input */, component).c_str();
- break;
- case C2Component::KIND_ENCODER:
- mCodingMediaType = QueryMediaType(false /* input */, component).c_str();
- break;
- default:
- mCodingMediaType = "";
- }
-
- c2err = component->querySupportedParams(&mParamDescs);
- if (c2err != C2_OK) {
- ALOGD("Query supported params failed after returning %zu values => %s",
- mParamDescs.size(), asString(c2err));
- return UNKNOWN_ERROR;
- }
- for (const std::shared_ptr<C2ParamDescriptor> &desc : mParamDescs) {
- mSupportedIndices.emplace(desc->index());
- }
-
- mReflector = client->getParamReflector();
- if (mReflector == nullptr) {
- ALOGE("Failed to get param reflector");
- return UNKNOWN_ERROR;
- }
-
- // enumerate all fields
- mParamUpdater = std::make_shared<ReflectedParamUpdater>();
- mParamUpdater->clear();
- mParamUpdater->supportWholeParam(
- C2_PARAMKEY_TEMPORAL_LAYERING, C2StreamTemporalLayeringTuning::CORE_INDEX);
- mParamUpdater->addParamDesc(mReflector, mParamDescs);
-
- // TEMP: add some standard fields even if not reflected
- if (kind.value == C2Component::KIND_ENCODER) {
- mParamUpdater->addStandardParam<C2StreamInitDataInfo::output>(C2_PARAMKEY_INIT_DATA);
- }
- if (domain.value == C2Component::DOMAIN_IMAGE || domain.value == C2Component::DOMAIN_VIDEO) {
- if (kind.value != C2Component::KIND_ENCODER) {
- addLocalParam<C2StreamPictureSizeInfo::output>(C2_PARAMKEY_PICTURE_SIZE);
- addLocalParam<C2StreamCropRectInfo::output>(C2_PARAMKEY_CROP_RECT);
- addLocalParam(
- new C2StreamPixelAspectRatioInfo::output(0u, 1u, 1u),
- C2_PARAMKEY_PIXEL_ASPECT_RATIO);
- addLocalParam(new C2StreamRotationInfo::output(0u, 0), C2_PARAMKEY_ROTATION);
- addLocalParam(new C2StreamColorAspectsInfo::output(0u), C2_PARAMKEY_COLOR_ASPECTS);
- addLocalParam<C2StreamDataSpaceInfo::output>(C2_PARAMKEY_DATA_SPACE);
- addLocalParam<C2StreamHdrStaticInfo::output>(C2_PARAMKEY_HDR_STATIC_INFO);
- addLocalParam(new C2StreamSurfaceScalingInfo::output(0u, VIDEO_SCALING_MODE_SCALE_TO_FIT),
- C2_PARAMKEY_SURFACE_SCALING_MODE);
- } else {
- addLocalParam(new C2StreamColorAspectsInfo::input(0u), C2_PARAMKEY_COLOR_ASPECTS);
- }
- }
-
- initializeStandardParams();
-
- // subscribe to all supported standard (exposed) params
- // TODO: limit this to params that are actually in the domain
- std::vector<std::string> formatKeys = mStandardParams->getPathsForDomain(Domain(1 << 30));
- std::vector<C2Param::Index> indices;
- mParamUpdater->getParamIndicesForKeys(formatKeys, &indices);
- mSubscribedIndices.insert(indices.begin(), indices.end());
-
- // also subscribe to some non-SDK standard parameters
- // for number of input/output buffers
- mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::input::PARAM_TYPE);
- mSubscribedIndices.emplace(C2PortSuggestedBufferCountTuning::output::PARAM_TYPE);
- mSubscribedIndices.emplace(C2ActualPipelineDelayTuning::PARAM_TYPE);
- mSubscribedIndices.emplace(C2PortActualDelayTuning::input::PARAM_TYPE);
- mSubscribedIndices.emplace(C2PortActualDelayTuning::output::PARAM_TYPE);
- // for output buffer array allocation
- mSubscribedIndices.emplace(C2StreamMaxBufferSizeInfo::output::PARAM_TYPE);
- // init data (CSD)
- mSubscribedIndices.emplace(C2StreamInitDataInfo::output::PARAM_TYPE);
-
- return OK;
-}
-
-status_t CCodecConfig::subscribeToConfigUpdate(
- const std::shared_ptr<Codec2Client::Component> &component,
- const std::vector<C2Param::Index> &indices,
- c2_blocking_t blocking) {
- mSubscribedIndices.insert(indices.begin(), indices.end());
- // TODO: enable this when components no longer crash on this config
- if (mSubscribedIndices.size() != mSubscribedIndicesSize && false) {
- std::vector<uint32_t> indices;
- for (C2Param::Index ix : mSubscribedIndices) {
- indices.push_back(ix);
- }
- std::unique_ptr<C2SubscribedParamIndicesTuning> subscribeTuning =
- C2SubscribedParamIndicesTuning::AllocUnique(indices);
- std::vector<std::unique_ptr<C2SettingResult>> results;
- c2_status_t c2Err = component->config({ subscribeTuning.get() }, blocking, &results);
- if (c2Err != C2_OK && c2Err != C2_BAD_INDEX) {
- ALOGD("Failed to subscribe to parameters => %s", asString(c2Err));
- // TODO: error
- }
- ALOGV("Subscribed to %zu params", mSubscribedIndices.size());
- mSubscribedIndicesSize = mSubscribedIndices.size();
- }
- return OK;
-}
-
-status_t CCodecConfig::queryConfiguration(
- const std::shared_ptr<Codec2Client::Component> &component) {
- // query all subscribed parameters
- std::vector<C2Param::Index> indices(mSubscribedIndices.begin(), mSubscribedIndices.end());
- std::vector<std::unique_ptr<C2Param>> queried;
- c2_status_t c2Err = component->query({}, indices, C2_MAY_BLOCK, &queried);
- if (c2Err != OK) {
- ALOGI("query failed after returning %zu values (%s)", queried.size(), asString(c2Err));
- // TODO: error
- }
-
- updateConfiguration(queried, ALL);
- return OK;
-}
-
-bool CCodecConfig::updateConfiguration(
- std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain) {
- ALOGV("updating configuration with %zu params", configUpdate.size());
- bool changed = false;
- for (std::unique_ptr<C2Param> &p : configUpdate) {
- if (p && *p) {
- auto insertion = mCurrentConfig.emplace(p->index(), nullptr);
- if (insertion.second || *insertion.first->second != *p) {
- if (mSupportedIndices.count(p->index()) || mLocalParams.count(p->index())) {
- // only track changes in supported (reflected or local) indices
- changed = true;
- } else {
- ALOGV("an unlisted config was %s: %#x",
- insertion.second ? "added" : "updated", p->index());
- }
- }
- insertion.first->second = std::move(p);
- }
- }
-
- ALOGV("updated configuration has %zu params (%s)", mCurrentConfig.size(),
- changed ? "CHANGED" : "no change");
- if (changed) {
- return updateFormats(domain);
- }
- return false;
-}
-
-bool CCodecConfig::updateFormats(Domain domain) {
- // get addresses of params in the current config
- std::vector<C2Param*> paramPointers;
- for (const auto &it : mCurrentConfig) {
- paramPointers.push_back(it.second.get());
- }
-
- ReflectedParamUpdater::Dict reflected = mParamUpdater->getParams(paramPointers);
- ALOGD("c2 config is %s", reflected.debugString().c_str());
-
- bool changed = false;
- if (domain & mInputDomain) {
- sp<AMessage> oldFormat = mInputFormat;
- mInputFormat = mInputFormat->dup(); // trigger format changed
- mInputFormat->extend(getSdkFormatForDomain(reflected, mInputDomain));
- if (mInputFormat->countEntries() != oldFormat->countEntries()
- || mInputFormat->changesFrom(oldFormat)->countEntries() > 0) {
- changed = true;
- } else {
- mInputFormat = oldFormat; // no change
- }
- }
- if (domain & mOutputDomain) {
- sp<AMessage> oldFormat = mOutputFormat;
- mOutputFormat = mOutputFormat->dup(); // trigger output format changed
- mOutputFormat->extend(getSdkFormatForDomain(reflected, mOutputDomain));
- if (mOutputFormat->countEntries() != oldFormat->countEntries()
- || mOutputFormat->changesFrom(oldFormat)->countEntries() > 0) {
- changed = true;
- } else {
- mOutputFormat = oldFormat; // no change
- }
- }
- ALOGV_IF(changed, "format(s) changed");
- return changed;
-}
-
-sp<AMessage> CCodecConfig::getSdkFormatForDomain(
- const ReflectedParamUpdater::Dict &reflected, Domain portDomain) const {
- sp<AMessage> msg = new AMessage;
- for (const std::pair<std::string, std::vector<ConfigMapper>> &el : mStandardParams->getKeys()) {
- for (const ConfigMapper &cm : el.second) {
- if ((cm.domain() & portDomain) == 0 // input-output-coded-raw
- || (cm.domain() & mDomain) != mDomain // component domain + kind (these must match)
- || (cm.domain() & IS_READ) == 0) {
- continue;
- }
- auto it = reflected.find(cm.path());
- if (it == reflected.end()) {
- continue;
- }
- C2Value c2Value;
- sp<ABuffer> bufValue;
- AString strValue;
- AMessage::ItemData item;
- if (it->second.find(&c2Value)) {
- item = cm.mapToMessage(c2Value);
- } else if (it->second.find(&bufValue)) {
- item.set(bufValue);
- } else if (it->second.find(&strValue)) {
- item.set(strValue);
- } else {
- ALOGD("unexpected untyped query value for key: %s", cm.path().c_str());
- continue;
- }
- msg->setItem(el.first.c_str(), item);
- }
- }
-
- { // convert from Codec 2.0 rect to MediaFormat rect and add crop rect if not present
- int32_t left, top, width, height;
- if (msg->findInt32("crop-left", &left) && msg->findInt32("crop-width", &width)
- && msg->findInt32("crop-top", &top) && msg->findInt32("crop-height", &height)
- && left >= 0 && width >=0 && width <= INT32_MAX - left
- && top >= 0 && height >=0 && height <= INT32_MAX - top) {
- msg->removeEntryAt(msg->findEntryByName("crop-left"));
- msg->removeEntryAt(msg->findEntryByName("crop-top"));
- msg->removeEntryAt(msg->findEntryByName("crop-width"));
- msg->removeEntryAt(msg->findEntryByName("crop-height"));
- msg->setRect("crop", left, top, left + width - 1, top + height - 1);
- } else if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
- msg->setRect("crop", 0, 0, width - 1, height - 1);
- }
- }
-
- { // convert temporal layering to schema
- sp<ABuffer> tmp;
- if (msg->findBuffer(C2_PARAMKEY_TEMPORAL_LAYERING, &tmp) && tmp != nullptr) {
- C2StreamTemporalLayeringTuning *layering =
- C2StreamTemporalLayeringTuning::From(C2Param::From(tmp->data(), tmp->size()));
- if (layering && layering->m.layerCount > 0
- && layering->m.bLayerCount < layering->m.layerCount) {
- // check if this is webrtc compatible
- AString mime;
- if (msg->findString(KEY_MIME, &mime) &&
- mime.equalsIgnoreCase(MIMETYPE_VIDEO_VP8) &&
- layering->m.bLayerCount == 0 &&
- (layering->m.layerCount == 1
- || (layering->m.layerCount == 2
- && layering->flexCount() >= 1
- && layering->m.bitrateRatios[0] == .6f)
- || (layering->m.layerCount == 3
- && layering->flexCount() >= 2
- && layering->m.bitrateRatios[0] == .4f
- && layering->m.bitrateRatios[1] == .6f)
- || (layering->m.layerCount == 4
- && layering->flexCount() >= 3
- && layering->m.bitrateRatios[0] == .25f
- && layering->m.bitrateRatios[1] == .4f
- && layering->m.bitrateRatios[2] == .6f))) {
- msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
- "webrtc.vp8.%u-layer", layering->m.layerCount));
- } else if (layering->m.bLayerCount) {
- msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
- "android.generic.%u+%u",
- layering->m.layerCount - layering->m.bLayerCount,
- layering->m.bLayerCount));
- } else if (layering->m.bLayerCount) {
- msg->setString(KEY_TEMPORAL_LAYERING, AStringPrintf(
- "android.generic.%u", layering->m.layerCount));
- }
- }
- msg->removeEntryAt(msg->findEntryByName(C2_PARAMKEY_TEMPORAL_LAYERING));
- }
- }
-
- { // convert color info
- C2Color::primaries_t primaries;
- C2Color::matrix_t matrix;
- if (msg->findInt32("color-primaries", (int32_t*)&primaries)
- && msg->findInt32("color-matrix", (int32_t*)&matrix)) {
- int32_t standard;
-
- if (C2Mapper::map(primaries, matrix, &standard)) {
- msg->setInt32(KEY_COLOR_STANDARD, standard);
- }
-
- msg->removeEntryAt(msg->findEntryByName("color-primaries"));
- msg->removeEntryAt(msg->findEntryByName("color-matrix"));
- }
-
-
- // calculate dataspace for raw graphic buffers if not specified by component, or if
- // using surface with unspecified aspects (as those must be defaulted which may change
- // the dataspace)
- if ((portDomain & IS_RAW) && (mDomain & (IS_IMAGE | IS_VIDEO))) {
- android_dataspace dataspace;
- ColorAspects aspects = {
- ColorAspects::RangeUnspecified, ColorAspects::PrimariesUnspecified,
- ColorAspects::TransferUnspecified, ColorAspects::MatrixUnspecified
- };
- ColorUtils::getColorAspectsFromFormat(msg, aspects);
- ColorAspects origAspects = aspects;
- if (mUsingSurface) {
- // get image size (default to HD)
- int32_t width = 1280;
- int32_t height = 720;
- int32_t left, top, right, bottom;
- if (msg->findRect("crop", &left, &top, &right, &bottom)) {
- width = right - left + 1;
- height = bottom - top + 1;
- } else {
- (void)msg->findInt32(KEY_WIDTH, &width);
- (void)msg->findInt32(KEY_HEIGHT, &height);
- }
- ColorUtils::setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
- ColorUtils::setColorAspectsIntoFormat(aspects, msg);
- }
-
- if (!msg->findInt32("android._dataspace", (int32_t*)&dataspace)
- || aspects.mRange != origAspects.mRange
- || aspects.mPrimaries != origAspects.mPrimaries
- || aspects.mTransfer != origAspects.mTransfer
- || aspects.mMatrixCoeffs != origAspects.mMatrixCoeffs) {
- dataspace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
- msg->setInt32("android._dataspace", dataspace);
- }
- }
-
- // HDR static info
-
- C2HdrStaticMetadataStruct hdr;
- if (msg->findFloat("smpte2086.red.x", &hdr.mastering.red.x)
- && msg->findFloat("smpte2086.red.y", &hdr.mastering.red.y)
- && msg->findFloat("smpte2086.green.x", &hdr.mastering.green.x)
- && msg->findFloat("smpte2086.green.y", &hdr.mastering.green.y)
- && msg->findFloat("smpte2086.blue.x", &hdr.mastering.blue.x)
- && msg->findFloat("smpte2086.blue.y", &hdr.mastering.blue.y)
- && msg->findFloat("smpte2086.white.x", &hdr.mastering.white.x)
- && msg->findFloat("smpte2086.white.y", &hdr.mastering.white.y)
- && msg->findFloat("smpte2086.max-luminance", &hdr.mastering.maxLuminance)
- && msg->findFloat("smpte2086.min-luminance", &hdr.mastering.minLuminance)
- && msg->findFloat("cta861.max-cll", &hdr.maxCll)
- && msg->findFloat("cta861.max-fall", &hdr.maxFall)) {
- if (hdr.mastering.red.x >= 0 && hdr.mastering.red.x <= 1
- && hdr.mastering.red.y >= 0 && hdr.mastering.red.y <= 1
- && hdr.mastering.green.x >= 0 && hdr.mastering.green.x <= 1
- && hdr.mastering.green.y >= 0 && hdr.mastering.green.y <= 1
- && hdr.mastering.blue.x >= 0 && hdr.mastering.blue.x <= 1
- && hdr.mastering.blue.y >= 0 && hdr.mastering.blue.y <= 1
- && hdr.mastering.white.x >= 0 && hdr.mastering.white.x <= 1
- && hdr.mastering.white.y >= 0 && hdr.mastering.white.y <= 1
- && hdr.mastering.maxLuminance >= 0 && hdr.mastering.maxLuminance <= 65535
- && hdr.mastering.minLuminance >= 0 && hdr.mastering.minLuminance <= 6.5535
- && hdr.maxCll >= 0 && hdr.maxCll <= 65535
- && hdr.maxFall >= 0 && hdr.maxFall <= 65535) {
- HDRStaticInfo meta;
- meta.mID = meta.kType1;
- meta.sType1.mR.x = hdr.mastering.red.x / 0.00002 + 0.5;
- meta.sType1.mR.y = hdr.mastering.red.y / 0.00002 + 0.5;
- meta.sType1.mG.x = hdr.mastering.green.x / 0.00002 + 0.5;
- meta.sType1.mG.y = hdr.mastering.green.y / 0.00002 + 0.5;
- meta.sType1.mB.x = hdr.mastering.blue.x / 0.00002 + 0.5;
- meta.sType1.mB.y = hdr.mastering.blue.y / 0.00002 + 0.5;
- meta.sType1.mW.x = hdr.mastering.white.x / 0.00002 + 0.5;
- meta.sType1.mW.y = hdr.mastering.white.y / 0.00002 + 0.5;
- meta.sType1.mMaxDisplayLuminance = hdr.mastering.maxLuminance + 0.5;
- meta.sType1.mMinDisplayLuminance = hdr.mastering.minLuminance / 0.0001 + 0.5;
- meta.sType1.mMaxContentLightLevel = hdr.maxCll + 0.5;
- meta.sType1.mMaxFrameAverageLightLevel = hdr.maxFall + 0.5;
- msg->removeEntryAt(msg->findEntryByName("smpte2086.red.x"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.red.y"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.green.x"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.green.y"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.x"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.blue.y"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.white.x"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.white.y"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.max-luminance"));
- msg->removeEntryAt(msg->findEntryByName("smpte2086.min-luminance"));
- msg->removeEntryAt(msg->findEntryByName("cta861.max-cll"));
- msg->removeEntryAt(msg->findEntryByName("cta861.max-fall"));
- msg->setBuffer(KEY_HDR_STATIC_INFO, ABuffer::CreateAsCopy(&meta, sizeof(meta)));
- } else {
- ALOGD("found invalid HDR static metadata %s", msg->debugString(8).c_str());
- }
- }
- }
-
- ALOGV("converted to SDK values as %s", msg->debugString().c_str());
- return msg;
-}
-
-/// converts an AMessage value to a ParamUpdater value
-static void convert(const AMessage::ItemData &from, ReflectedParamUpdater::Value *to) {
- int32_t int32Value;
- int64_t int64Value;
- sp<ABuffer> bufValue;
- AString strValue;
- float floatValue;
- double doubleValue;
-
- if (from.find(&int32Value)) {
- to->set(int32Value);
- } else if (from.find(&int64Value)) {
- to->set(int64Value);
- } else if (from.find(&bufValue)) {
- to->set(bufValue);
- } else if (from.find(&strValue)) {
- to->set(strValue);
- } else if (from.find(&floatValue)) {
- to->set(C2Value(floatValue));
- } else if (from.find(&doubleValue)) {
- // convert double to float
- to->set(C2Value((float)doubleValue));
- }
- // ignore all other AMessage types
-}
-
-/// relaxes Codec 2.0 specific value types to SDK types (mainly removes signedness and counterness
-/// from 32/64-bit values.)
-static void relaxValues(ReflectedParamUpdater::Value &item) {
- C2Value c2Value;
- int32_t int32Value;
- int64_t int64Value;
- (void)item.find(&c2Value);
- if (c2Value.get(&int32Value) || c2Value.get((uint32_t*)&int32Value)
- || c2Value.get((c2_cntr32_t*)&int32Value)) {
- item.set(int32Value);
- } else if (c2Value.get(&int64Value)
- || c2Value.get((uint64_t*)&int64Value)
- || c2Value.get((c2_cntr64_t*)&int64Value)) {
- item.set(int64Value);
- }
-}
-
-ReflectedParamUpdater::Dict CCodecConfig::getReflectedFormat(
- const sp<AMessage> &params_, Domain configDomain) const {
- // create a modifiable copy of params
- sp<AMessage> params = params_->dup();
- ALOGV("filtering with config domain %x", configDomain);
-
- // convert some macro parameters to Codec 2.0 specific expressions
-
- { // make i-frame-interval frame based
- float iFrameInterval;
- if (params->findAsFloat(KEY_I_FRAME_INTERVAL, &iFrameInterval)) {
- float frameRate;
- if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
- params->setInt32("i-frame-period",
- (frameRate <= 0 || iFrameInterval < 0)
- ? -1 /* no sync frames */
- : (int32_t)c2_min(iFrameInterval * frameRate + 0.5,
- (float)INT32_MAX));
- }
- }
- }
-
- if (mDomain == (IS_VIDEO | IS_ENCODER)) {
- // convert capture-rate into input-time-stretch
- float frameRate, captureRate;
- if (params->findAsFloat(KEY_FRAME_RATE, &frameRate)) {
- if (!params->findAsFloat("time-lapse-fps", &captureRate)
- && !params->findAsFloat(KEY_CAPTURE_RATE, &captureRate)) {
- captureRate = frameRate;
- }
- if (captureRate > 0 && frameRate > 0) {
- params->setFloat(C2_PARAMKEY_INPUT_TIME_STRETCH, captureRate / frameRate);
- }
- }
- }
-
- { // reflect temporal layering into a binary blob
- AString schema;
- if (params->findString(KEY_TEMPORAL_LAYERING, &schema)) {
- unsigned int numLayers = 0;
- unsigned int numBLayers = 0;
- int tags;
- char dummy;
- std::unique_ptr<C2StreamTemporalLayeringTuning::output> layering;
- if (sscanf(schema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
- && numLayers > 0) {
- switch (numLayers) {
- case 1:
- layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
- {}, 0u, 1u, 0u);
- break;
- case 2:
- layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
- { .6f }, 0u, 2u, 0u);
- break;
- case 3:
- layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
- { .4f, .6f }, 0u, 3u, 0u);
- break;
- default:
- layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
- { .25f, .4f, .6f }, 0u, 4u, 0u);
- break;
- }
- } else if ((tags = sscanf(schema.c_str(), "android.generic.%u%c%u%c",
- &numLayers, &dummy, &numBLayers, &dummy))
- && (tags == 1 || (tags == 3 && dummy == '+'))
- && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
- layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
- {}, 0u, numLayers + numBLayers, numBLayers);
- } else {
- ALOGD("Ignoring unsupported ts-schema [%s]", schema.c_str());
- }
- if (layering) {
- params->setBuffer(C2_PARAMKEY_TEMPORAL_LAYERING,
- ABuffer::CreateAsCopy(layering.get(), layering->size()));
- }
- }
- }
-
- { // convert from MediaFormat rect to Codec 2.0 rect
- int32_t offset;
- int32_t end;
- AMessage::ItemData item;
- if (params->findInt32("crop-left", &offset) && params->findInt32("crop-right", &end)
- && offset >= 0 && end >= offset - 1) {
- size_t ix = params->findEntryByName("crop-right");
- params->setEntryNameAt(ix, "crop-width");
- item.set(end - offset + 1);
- params->setEntryAt(ix, item);
- }
- if (params->findInt32("crop-top", &offset) && params->findInt32("crop-bottom", &end)
- && offset >= 0 && end >= offset - 1) {
- size_t ix = params->findEntryByName("crop-bottom");
- params->setEntryNameAt(ix, "crop-height");
- item.set(end - offset + 1);
- params->setEntryAt(ix, item);
- }
- }
-
- { // convert color info
- int32_t standard;
- if (params->findInt32(KEY_COLOR_STANDARD, &standard)) {
- C2Color::primaries_t primaries;
- C2Color::matrix_t matrix;
-
- if (C2Mapper::map(standard, &primaries, &matrix)) {
- params->setInt32("color-primaries", primaries);
- params->setInt32("color-matrix", matrix);
- }
- }
-
- sp<ABuffer> hdrMeta;
- if (params->findBuffer(KEY_HDR_STATIC_INFO, &hdrMeta)
- && hdrMeta->size() == sizeof(HDRStaticInfo)) {
- HDRStaticInfo *meta = (HDRStaticInfo*)hdrMeta->data();
- if (meta->mID == meta->kType1) {
- params->setFloat("smpte2086.red.x", meta->sType1.mR.x * 0.00002);
- params->setFloat("smpte2086.red.y", meta->sType1.mR.y * 0.00002);
- params->setFloat("smpte2086.green.x", meta->sType1.mG.x * 0.00002);
- params->setFloat("smpte2086.green.y", meta->sType1.mG.y * 0.00002);
- params->setFloat("smpte2086.blue.x", meta->sType1.mB.x * 0.00002);
- params->setFloat("smpte2086.blue.y", meta->sType1.mB.y * 0.00002);
- params->setFloat("smpte2086.white.x", meta->sType1.mW.x * 0.00002);
- params->setFloat("smpte2086.white.y", meta->sType1.mW.y * 0.00002);
- params->setFloat("smpte2086.max-luminance", meta->sType1.mMaxDisplayLuminance);
- params->setFloat("smpte2086.min-luminance", meta->sType1.mMinDisplayLuminance * 0.0001);
- params->setFloat("cta861.max-cll", meta->sType1.mMaxContentLightLevel);
- params->setFloat("cta861.max-fall", meta->sType1.mMaxFrameAverageLightLevel);
- }
- }
- }
-
- // this is to verify that we set proper signedness for standard parameters
- bool beVeryStrict = property_get_bool("debug.stagefright.ccodec_strict_type", false);
- // this is to allow vendors to use the wrong signedness for standard parameters
- bool beVeryLax = property_get_bool("debug.stagefright.ccodec_lax_type", false);
-
- ReflectedParamUpdater::Dict filtered;
- for (size_t ix = 0; ix < params->countEntries(); ++ix) {
- AMessage::Type type;
- AString name = params->getEntryNameAt(ix, &type);
- AMessage::ItemData msgItem = params->getEntryAt(ix);
- ReflectedParamUpdater::Value item;
- convert(msgItem, &item); // convert item to param updater item
-
- if (name.startsWith("vendor.")) {
- // vendor params pass through as is
- filtered.emplace(name.c_str(), item);
- continue;
- }
- // standard parameters may get modified, filtered or duplicated
- for (const ConfigMapper &cm : mStandardParams->getConfigMappersForSdkKey(name.c_str())) {
- // note: we ignore port domain for configuration
- if ((cm.domain() & configDomain)
- // component domain + kind (these must match)
- && (cm.domain() & mDomain) == mDomain) {
- // map arithmetic values, pass through string or buffer
- switch (type) {
- case AMessage::kTypeBuffer:
- case AMessage::kTypeString:
- break;
- case AMessage::kTypeInt32:
- case AMessage::kTypeInt64:
- case AMessage::kTypeFloat:
- case AMessage::kTypeDouble:
- // for now only map settings with mappers as we are not creating
- // signed <=> unsigned mappers
- // TODO: be precise about signed unsigned
- if (beVeryStrict || cm.mapper()) {
- item.set(cm.mapFromMessage(params->getEntryAt(ix)));
- // also allow to relax type strictness
- if (beVeryLax) {
- relaxValues(item);
- }
- }
- break;
- default:
- continue;
- }
- filtered.emplace(cm.path(), item);
- }
- }
- }
- ALOGV("filtered %s to %s", params->debugString(4).c_str(),
- filtered.debugString(4).c_str());
- return filtered;
-}
-
-status_t CCodecConfig::getConfigUpdateFromSdkParams(
- std::shared_ptr<Codec2Client::Component> component,
- const sp<AMessage> &sdkParams, Domain configDomain,
- c2_blocking_t blocking,
- std::vector<std::unique_ptr<C2Param>> *configUpdate) const {
- ReflectedParamUpdater::Dict params = getReflectedFormat(sdkParams, configDomain);
-
- std::vector<C2Param::Index> indices;
- mParamUpdater->getParamIndicesFromMessage(params, &indices);
- if (indices.empty()) {
- ALOGD("no recognized params in: %s", params.debugString().c_str());
- return OK;
- }
-
- configUpdate->clear();
- std::vector<C2Param::Index> supportedIndices;
- for (C2Param::Index ix : indices) {
- if (mSupportedIndices.count(ix)) {
- supportedIndices.push_back(ix);
- } else if (mLocalParams.count(ix)) {
- // query local parameter here
- auto it = mCurrentConfig.find(ix);
- if (it != mCurrentConfig.end()) {
- configUpdate->emplace_back(C2Param::Copy(*it->second));
- }
- }
- }
-
- c2_status_t err = component->query({ }, supportedIndices, blocking, configUpdate);
- if (err != C2_OK) {
- ALOGD("query failed after returning %zu params => %s", configUpdate->size(), asString(err));
- }
-
- if (configUpdate->size()) {
- mParamUpdater->updateParamsFromMessage(params, configUpdate);
- }
- return OK;
-}
-
-status_t CCodecConfig::setParameters(
- std::shared_ptr<Codec2Client::Component> component,
- std::vector<std::unique_ptr<C2Param>> &configUpdate,
- c2_blocking_t blocking) {
- status_t result = OK;
- if (configUpdate.empty()) {
- return OK;
- }
-
- std::vector<C2Param::Index> indices;
- std::vector<C2Param *> paramVector;
- for (const std::unique_ptr<C2Param> &param : configUpdate) {
- if (mSupportedIndices.count(param->index())) {
- // component parameter
- paramVector.push_back(param.get());
- indices.push_back(param->index());
- } else if (mLocalParams.count(param->index())) {
- // handle local parameter here
- LocalParamValidator validator = mLocalParams.find(param->index())->second;
- c2_status_t err = C2_OK;
- std::unique_ptr<C2Param> copy = C2Param::Copy(*param);
- if (validator) {
- err = validator(copy);
- }
- if (err == C2_OK) {
- ALOGV("updated local parameter value for %s",
- mParamUpdater->getParamName(param->index()).c_str());
-
- mCurrentConfig[param->index()] = std::move(copy);
- } else {
- ALOGD("failed to set parameter value for %s => %s",
- mParamUpdater->getParamName(param->index()).c_str(), asString(err));
- result = BAD_VALUE;
- }
- }
- }
- // update subscribed param indices
- subscribeToConfigUpdate(component, indices, blocking);
-
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- c2_status_t err = component->config(paramVector, blocking, &failures);
- if (err != C2_OK) {
- ALOGD("config failed => %s", asString(err));
- // This is non-fatal.
- }
- for (const std::unique_ptr<C2SettingResult> &failure : failures) {
- switch (failure->failure) {
- case C2SettingResult::BAD_VALUE:
- ALOGD("Bad parameter value");
- result = BAD_VALUE;
- break;
- default:
- ALOGV("failure = %d", int(failure->failure));
- break;
- }
- }
-
- // Re-query parameter values in case config could not update them and update the current
- // configuration.
- configUpdate.clear();
- err = component->query({}, indices, blocking, &configUpdate);
- if (err != C2_OK) {
- ALOGD("query failed after returning %zu params => %s", configUpdate.size(), asString(err));
- }
- (void)updateConfiguration(configUpdate, ALL);
-
- // TODO: error value
- return result;
-}
-
-const C2Param *CCodecConfig::getConfigParameterValue(C2Param::Index index) const {
- auto it = mCurrentConfig.find(index);
- if (it == mCurrentConfig.end()) {
- return nullptr;
- } else {
- return it->second.get();
- }
-}
-
-} // namespace android
diff --git a/media/sfplugin/CCodecConfig.h b/media/sfplugin/CCodecConfig.h
deleted file mode 100644
index 3bafe3f..0000000
--- a/media/sfplugin/CCodecConfig.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef C_CODEC_CONFIG_H_
-#define C_CODEC_CONFIG_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <vector>
-
-#include <C2Component.h>
-#include <codec2/hidl/client.h>
-
-#include <utils/RefBase.h>
-
-#include "InputSurfaceWrapper.h"
-#include "ReflectedParamUpdater.h"
-
-namespace android {
-
-struct AMessage;
-struct StandardParams;
-
-/**
- * Struct managing the codec configuration for CCodec.
- */
-struct CCodecConfig {
-
- /**
- * Domain consists of a bitmask divided into fields, and specifiers work by excluding other
- * values in those domains.
- *
- * Component domains are composed by or-ing the individual IS_ constants, e.g.
- * IS_DECODER | IS_AUDIO.
- *
- * Config specifiers are composed by or-ing the individual mask constants, and
- * and-ing these groups: e.g. (DECODER | ENCODER) & AUDIO.
- *
- * The naming of these constants was to limit the length of mask names as these are used more
- * commonly as masks.
- */
- enum Domain : uint32_t {
- // component domain (domain & kind)
- GUARD_BIT = (1 << 1), ///< this is to prevent against accidental && or || usage
- IS_AUDIO = (1 << 2), ///< for audio codecs
- IS_VIDEO = (1 << 3), ///< for video codecs
- IS_IMAGE = (1 << 4), ///< for image codecs
- OTHER_DOMAIN = (1 << 5), ///< for other domains
-
- IS_ENCODER = (1 << 6), ///< for encoders
- IS_DECODER = (1 << 7), ///< for decoders
- OTHER_KIND = (1 << 8), ///< for other domains
-
- // config domain
- IS_PARAM = (1 << 9), ///< for setParameter
- IS_CONFIG = (1 << 10), ///< for configure
- IS_READ = (1 << 11), ///< for getFormat
-
- // port domain
- IS_INPUT = (1 << 12), ///< for input port (getFormat)
- IS_OUTPUT = (1 << 13), ///< for output port (getFormat)
- IS_RAW = (1 << 14), ///< for raw port (input-encoder, output-decoder)
- IS_CODED = (1 << 15), ///< for coded port (input-decoder, output-encoder)
-
- ALL = ~0U,
- NONE = 0,
-
- AUDIO = ~(IS_IMAGE | IS_VIDEO | OTHER_DOMAIN),
- VIDEO = ~(IS_AUDIO | IS_IMAGE | OTHER_DOMAIN),
- IMAGE = ~(IS_AUDIO | IS_VIDEO | OTHER_DOMAIN),
-
- DECODER = ~(IS_ENCODER | OTHER_KIND),
- ENCODER = ~(IS_DECODER | OTHER_KIND),
-
- PARAM = ~(IS_CONFIG | IS_READ),
- CONFIG = ~(IS_PARAM | IS_READ),
- READ = ~(IS_CONFIG | IS_PARAM),
-
- INPUT = ~(IS_OUTPUT | IS_RAW | IS_CODED),
- OUTPUT = ~(IS_INPUT | IS_RAW | IS_CODED),
- RAW = ~(IS_INPUT | IS_OUTPUT | IS_CODED),
- CODED = ~(IS_INPUT | IS_RAW | IS_OUTPUT),
- };
-
- // things required to manage formats
- std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
- std::shared_ptr<C2ParamReflector> mReflector;
-
- std::shared_ptr<ReflectedParamUpdater> mParamUpdater;
-
- Domain mDomain; // component domain
- Domain mInputDomain; // input port domain
- Domain mOutputDomain; // output port domain
- std::string mCodingMediaType; // media type of the coded stream
-
- // standard MediaCodec to Codec 2.0 params mapping
- std::shared_ptr<StandardParams> mStandardParams;
-
- std::set<C2Param::Index> mSupportedIndices; ///< indices supported by the component
- std::set<C2Param::Index> mSubscribedIndices; ///< indices to subscribe to
- size_t mSubscribedIndicesSize; ///< count of currently subscribed indices
-
- sp<AMessage> mInputFormat;
- sp<AMessage> mOutputFormat;
-
- bool mUsingSurface; ///< using input or output surface
-
- std::shared_ptr<InputSurfaceWrapper> mInputSurface;
- std::unique_ptr<InputSurfaceWrapper::Config> mISConfig;
-
- /// the current configuration. Updated after configure() and based on configUpdate in
- /// onWorkDone
- std::map<C2Param::Index, std::unique_ptr<C2Param>> mCurrentConfig;
-
- typedef std::function<c2_status_t(std::unique_ptr<C2Param>&)> LocalParamValidator;
-
- /// Parameter indices tracked in current config that are not supported by the component.
- /// these are provided so that optional parameters can remain in the current configuration.
- /// as such, these parameters have no dependencies. TODO: use C2InterfaceHelper for this.
- /// For now support a validation function.
- std::map<C2Param::Index, LocalParamValidator> mLocalParams;
-
- CCodecConfig();
-
- /// initializes the members required to manage the format: descriptors, reflector,
- /// reflected param helper, domain, standard params, and subscribes to standard
- /// indices.
- status_t initialize(
- const std::shared_ptr<Codec2Client> &client,
- const std::shared_ptr<Codec2Client::Component> &component);
-
-
- /**
- * Adds a locally maintained parameter. This is used for output configuration that can be
- * appended to the output buffers in case it is not supported by the component.
- */
- template<typename T>
- bool addLocalParam(
- const std::string &name,
- C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
- std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
- std::function<c2_status_t(std::unique_ptr<T>&)>()) {
- C2Param::Index index = T::PARAM_TYPE;
- if (mSupportedIndices.count(index) || mLocalParams.count(index)) {
- if (mSupportedIndices.count(index)) {
- mSubscribedIndices.emplace(index);
- }
- ALOGD("ignoring local param %s (%#x) as it is already %s",
- name.c_str(), (uint32_t)index, mSupportedIndices.count(index) ? "supported" : "local");
- return false; // already supported by the component or already added
- }
-
- // wrap typed validator into untyped validator
- LocalParamValidator validator;
- if (validator_) {
- validator = [validator_](std::unique_ptr<C2Param>& p){
- c2_status_t res = C2_BAD_VALUE;
- std::unique_ptr<T> typed(static_cast<T*>(p.release()));
- // if parameter is correctly typed
- if (T::From(typed.get())) {
- res = validator_(typed);
- p.reset(typed.release());
- }
- return res;
- };
- }
-
- mLocalParams.emplace(index, validator);
- mParamUpdater->addStandardParam<T>(name, attrib);
- return true;
- }
-
- /**
- * Adds a locally maintained parameter with a default value.
- */
- template<typename T>
- bool addLocalParam(
- std::unique_ptr<T> default_,
- const std::string &name,
- C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
- std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
- std::function<c2_status_t(std::unique_ptr<T>&)>()) {
- if (addLocalParam<T>(name, attrib, validator_)) {
- if (validator_) {
- c2_status_t err = validator_(default_);
- if (err != C2_OK) {
- ALOGD("default value for %s is invalid => %s", name.c_str(), asString(err));
- return false;
- }
- }
- mCurrentConfig[T::PARAM_TYPE] = std::move(default_);
- return true;
- }
- return false;
- }
-
- template<typename T>
- bool addLocalParam(
- T *default_, const std::string &name,
- C2ParamDescriptor::attrib_t attrib = C2ParamDescriptor::IS_READ_ONLY,
- std::function<c2_status_t(std::unique_ptr<T>&)> validator_ =
- std::function<c2_status_t(std::unique_ptr<T>&)>()) {
- return addLocalParam(std::unique_ptr<T>(default_), name, attrib, validator_);
- }
-
- /// Applies configuration updates, and updates format in the specific domain.
- /// Returns true if formats were updated
- /// \param domain input/output bitmask
- bool updateConfiguration(
- std::vector<std::unique_ptr<C2Param>> &configUpdate, Domain domain);
-
- /// Updates formats in the specific domain. Returns true if any of the formats have changed.
- /// \param domain input/output bitmask
- bool updateFormats(Domain domain);
-
- /**
- * Applies SDK configurations in a specific configuration domain.
- * Updates relevant input/output formats and subscribes to parameters specified in the
- * configuration.
- * \param domain config/setParam bitmask
- * \param blocking blocking mode to use with the component
- */
- status_t getConfigUpdateFromSdkParams(
- std::shared_ptr<Codec2Client::Component> component,
- const sp<AMessage> &sdkParams, Domain domain,
- c2_blocking_t blocking,
- std::vector<std::unique_ptr<C2Param>> *configUpdate) const;
-
- /**
- * Applies a configuration update to the component.
- * Updates relevant input/output formats and subscribes to parameters specified in the
- * configuration.
- * \param blocking blocking mode to use with the component
- */
- status_t setParameters(
- std::shared_ptr<Codec2Client::Component> component,
- std::vector<std::unique_ptr<C2Param>> &configUpdate,
- c2_blocking_t blocking);
-
- /// Queries subscribed indices (which contains all SDK-exposed values) and updates
- /// input/output formats.
- status_t queryConfiguration(
- const std::shared_ptr<Codec2Client::Component> &component);
-
- /// Queries a configuration parameter value. Returns nullptr if the parameter is not
- /// part of the current configuration
- const C2Param *getConfigParameterValue(C2Param::Index index) const;
-
- /**
- * Object that can be used to access configuration parameters and if they change.
- */
- template<typename T>
- struct Watcher {
- ~Watcher() = default;
-
- /// returns true if the value of this configuration has changed
- bool hasChanged() const {
- const C2Param *value = mParent->getConfigParameterValue(mIndex);
- if (value && mValue) {
- return *value != *mValue;
- } else {
- return value != mValue.get();
- }
- }
-
- /// updates the current value and returns it
- std::shared_ptr<const T> update() {
- const C2Param *value = mParent->getConfigParameterValue(mIndex);
- if (value) {
- mValue = std::shared_ptr<const T>(T::From(C2Param::Copy(*value).release()));
- }
- return mValue;
- }
-
- private:
- Watcher(C2Param::Index index, const CCodecConfig *parent)
- : mParent(parent), mIndex(index) {
- update();
- }
-
- friend struct CCodecConfig;
-
- const CCodecConfig *mParent;
- std::shared_ptr<const T> mValue;
- C2Param::Index mIndex;
- };
-
- /**
- * Returns a watcher object for a parameter.
- */
- template<typename T>
- Watcher<T> watch(C2Param::Index index = T::PARAM_TYPE) const {
- if (index.type() != T::PARAM_TYPE) {
- __builtin_trap();
- }
- return Watcher<T>(index, this);
- }
-
-private:
-
- /// initializes the standard MediaCodec to Codec 2.0 params mapping
- void initializeStandardParams();
-
- /// Adds indices to the subscribed indices, and updated subscription to component
- /// \param blocking blocking mode to use with the component
- status_t subscribeToConfigUpdate(
- const std::shared_ptr<Codec2Client::Component> &component,
- const std::vector<C2Param::Index> &indices,
- c2_blocking_t blocking = C2_DONT_BLOCK);
-
- /// Gets SDK format from codec 2.0 reflected configuration
- /// \param domain input/output bitmask
- sp<AMessage> getSdkFormatForDomain(
- const ReflectedParamUpdater::Dict &reflected, Domain domain) const;
-
- /**
- * Converts a set of configuration parameters in an AMessage to a list of path-based Codec
- * 2.0 configuration parameters.
- *
- * \param domain config/setParam bitmask
- */
- ReflectedParamUpdater::Dict getReflectedFormat(
- const sp<AMessage> &config, Domain domain) const;
-};
-
-DEFINE_ENUM_OPERATORS(CCodecConfig::Domain)
-
-} // namespace android
-
-#endif // C_CODEC_H_
-
diff --git a/media/sfplugin/Codec2Buffer.cpp b/media/sfplugin/Codec2Buffer.cpp
deleted file mode 100644
index 597e8f3..0000000
--- a/media/sfplugin/Codec2Buffer.cpp
+++ /dev/null
@@ -1,812 +0,0 @@
-/*
- * 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 "Codec2Buffer"
-#include <utils/Log.h>
-
-#include <hidlmemory/FrameworkUtils.h>
-#include <media/hardware/HardwareAPI.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <nativebase/nativebase.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2BlockInternal.h>
-#include <C2Debug.h>
-
-#include "Codec2Buffer.h"
-
-namespace android {
-
-// Codec2Buffer
-
-bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const {
- if (const_cast<Codec2Buffer *>(this)->base() == nullptr) {
- return false;
- }
- if (!buffer) {
- // Nothing to copy, so we can copy by doing nothing.
- return true;
- }
- if (buffer->data().type() != C2BufferData::LINEAR) {
- return false;
- }
- if (buffer->data().linearBlocks().size() == 0u) {
- // Nothing to copy, so we can copy by doing nothing.
- return true;
- } else if (buffer->data().linearBlocks().size() > 1u) {
- // We don't know how to copy more than one blocks.
- return false;
- }
- if (buffer->data().linearBlocks()[0].size() > capacity()) {
- // It won't fit.
- return false;
- }
- return true;
-}
-
-bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) {
- // We assume that all canCopyLinear() checks passed.
- if (!buffer || buffer->data().linearBlocks().size() == 0u
- || buffer->data().linearBlocks()[0].size() == 0u) {
- setRange(0, 0);
- return true;
- }
- C2ReadView view = buffer->data().linearBlocks()[0].map().get();
- if (view.error() != C2_OK) {
- ALOGD("Error while mapping: %d", view.error());
- return false;
- }
- if (view.capacity() > capacity()) {
- ALOGD("C2ConstLinearBlock lied --- it actually doesn't fit: view(%u) > this(%zu)",
- view.capacity(), capacity());
- return false;
- }
- memcpy(base(), view.data(), view.capacity());
- setRange(0, view.capacity());
- return true;
-}
-
-void Codec2Buffer::setImageData(const sp<ABuffer> &imageData) {
- meta()->setBuffer("image-data", imageData);
- format()->setBuffer("image-data", imageData);
- MediaImage2 *img = (MediaImage2*)imageData->data();
- if (img->mNumPlanes > 0 && img->mType != img->MEDIA_IMAGE_TYPE_UNKNOWN) {
- int32_t stride = img->mPlane[0].mRowInc;
- format()->setInt32(KEY_STRIDE, stride);
- if (img->mNumPlanes > 1 && stride > 0) {
- int32_t vstride = (img->mPlane[1].mOffset - img->mPlane[0].mOffset) / stride;
- format()->setInt32(KEY_SLICE_HEIGHT, vstride);
- }
- }
-}
-
-// LocalLinearBuffer
-
-bool LocalLinearBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
- return canCopyLinear(buffer);
-}
-
-bool LocalLinearBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
- return copyLinear(buffer);
-}
-
-// DummyContainerBuffer
-
-static uint8_t sDummyByte[1] = { 0 };
-
-DummyContainerBuffer::DummyContainerBuffer(
- const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer)
- : Codec2Buffer(format, new ABuffer(sDummyByte, 1)),
- mBufferRef(buffer) {
- setRange(0, buffer ? 1 : 0);
-}
-
-std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() {
- return std::move(mBufferRef);
-}
-
-bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const {
- return !mBufferRef;
-}
-
-bool DummyContainerBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
- mBufferRef = buffer;
- setRange(0, mBufferRef ? 1 : 0);
- return true;
-}
-
-// LinearBlockBuffer
-
-// static
-sp<LinearBlockBuffer> LinearBlockBuffer::Allocate(
- const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) {
- C2WriteView writeView(block->map().get());
- if (writeView.error() != C2_OK) {
- return nullptr;
- }
- return new LinearBlockBuffer(format, std::move(writeView), block);
-}
-
-std::shared_ptr<C2Buffer> LinearBlockBuffer::asC2Buffer() {
- return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
-}
-
-bool LinearBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
- return canCopyLinear(buffer);
-}
-
-bool LinearBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
- return copyLinear(buffer);
-}
-
-LinearBlockBuffer::LinearBlockBuffer(
- const sp<AMessage> &format,
- C2WriteView&& writeView,
- const std::shared_ptr<C2LinearBlock> &block)
- : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())),
- mWriteView(writeView),
- mBlock(block) {
-}
-
-// ConstLinearBlockBuffer
-
-// static
-sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::Allocate(
- const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) {
- if (!buffer
- || buffer->data().type() != C2BufferData::LINEAR
- || buffer->data().linearBlocks().size() != 1u) {
- return nullptr;
- }
- C2ReadView readView(buffer->data().linearBlocks()[0].map().get());
- if (readView.error() != C2_OK) {
- return nullptr;
- }
- return new ConstLinearBlockBuffer(format, std::move(readView), buffer);
-}
-
-ConstLinearBlockBuffer::ConstLinearBlockBuffer(
- const sp<AMessage> &format,
- C2ReadView&& readView,
- const std::shared_ptr<C2Buffer> &buffer)
- : Codec2Buffer(format, new ABuffer(
- // NOTE: ABuffer only takes non-const pointer but this data is
- // supposed to be read-only.
- const_cast<uint8_t *>(readView.data()), readView.capacity())),
- mReadView(readView),
- mBufferRef(buffer) {
-}
-
-std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() {
- return std::move(mBufferRef);
-}
-
-// GraphicView2MediaImageConverter
-
-namespace {
-
-class GraphicView2MediaImageConverter {
-public:
- /**
- * Creates a C2GraphicView <=> MediaImage converter
- *
- * \param view C2GraphicView object
- * \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
- * an attempt is made to simply represent the graphic view as a flexible SDK format
- * without a memcpy)
- */
- GraphicView2MediaImageConverter(
- const C2GraphicView &view, int32_t colorFormat)
- : mInitCheck(NO_INIT),
- mView(view),
- mWidth(view.width()),
- mHeight(view.height()),
- mColorFormat(colorFormat),
- mAllocatedDepth(0),
- mBackBufferSize(0),
- mMediaImage(new ABuffer(sizeof(MediaImage2))) {
- if (view.error() != C2_OK) {
- ALOGD("Converter: view.error() = %d", view.error());
- mInitCheck = BAD_VALUE;
- return;
- }
- MediaImage2 *mediaImage = (MediaImage2 *)mMediaImage->base();
- const C2PlanarLayout &layout = view.layout();
- if (layout.numPlanes == 0) {
- ALOGD("Converter: 0 planes");
- mInitCheck = BAD_VALUE;
- return;
- }
- mAllocatedDepth = layout.planes[0].allocatedDepth;
- uint32_t bitDepth = layout.planes[0].bitDepth;
-
- // align width and height to support subsampling cleanly
- uint32_t mStride = align(mWidth, 2) * divUp(layout.planes[0].allocatedDepth, 8u);
- uint32_t mVStride = align(mHeight, 2);
-
- switch (layout.type) {
- case C2PlanarLayout::TYPE_YUV:
- mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
- if (layout.numPlanes != 3) {
- ALOGD("Converter: %d planes for YUV layout", layout.numPlanes);
- mInitCheck = BAD_VALUE;
- return;
- }
- if (layout.planes[0].channel != C2PlaneInfo::CHANNEL_Y
- || layout.planes[1].channel != C2PlaneInfo::CHANNEL_CB
- || layout.planes[2].channel != C2PlaneInfo::CHANNEL_CR
- || layout.planes[0].colSampling != 1
- || layout.planes[0].rowSampling != 1
- || layout.planes[1].colSampling != 2
- || layout.planes[1].rowSampling != 2
- || layout.planes[2].colSampling != 2
- || layout.planes[2].rowSampling != 2) {
- ALOGD("Converter: not YUV420 for YUV layout");
- mInitCheck = BAD_VALUE;
- return;
- }
- switch (mColorFormat) {
- case COLOR_FormatYUV420Flexible:
- { // try to map directly. check if the planes are near one another
- const uint8_t *minPtr = mView.data()[0];
- const uint8_t *maxPtr = mView.data()[0];
- int32_t planeSize = 0;
- for (uint32_t i = 0; i < layout.numPlanes; ++i) {
- const C2PlaneInfo &plane = layout.planes[i];
- ssize_t minOffset = plane.minOffset(mWidth, mHeight);
- ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
- if (minPtr > mView.data()[i] + minOffset) {
- minPtr = mView.data()[i] + minOffset;
- }
- if (maxPtr < mView.data()[i] + maxOffset) {
- maxPtr = mView.data()[i] + maxOffset;
- }
- planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
- / plane.rowSampling / plane.colSampling * divUp(mAllocatedDepth, 8u);
- }
-
- if ((maxPtr - minPtr + 1) <= planeSize) {
- // FIXME: this is risky as reading/writing data out of bound results in
- // an undefined behavior, but gralloc does assume a contiguous
- // mapping
- for (uint32_t i = 0; i < layout.numPlanes; ++i) {
- const C2PlaneInfo &plane = layout.planes[i];
- mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
- mediaImage->mPlane[i].mColInc = plane.colInc;
- mediaImage->mPlane[i].mRowInc = plane.rowInc;
- mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
- mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
- }
- mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
- break;
- }
- }
- [[fallthrough]];
-
- case COLOR_FormatYUV420Planar:
- case COLOR_FormatYUV420PackedPlanar:
- mediaImage->mPlane[mediaImage->Y].mOffset = 0;
- mediaImage->mPlane[mediaImage->Y].mColInc = 1;
- mediaImage->mPlane[mediaImage->Y].mRowInc = mStride;
- mediaImage->mPlane[mediaImage->Y].mHorizSubsampling = 1;
- mediaImage->mPlane[mediaImage->Y].mVertSubsampling = 1;
-
- mediaImage->mPlane[mediaImage->U].mOffset = mStride * mVStride;
- mediaImage->mPlane[mediaImage->U].mColInc = 1;
- mediaImage->mPlane[mediaImage->U].mRowInc = mStride / 2;
- mediaImage->mPlane[mediaImage->U].mHorizSubsampling = 2;
- mediaImage->mPlane[mediaImage->U].mVertSubsampling = 2;
-
- mediaImage->mPlane[mediaImage->V].mOffset = mStride * mVStride * 5 / 4;
- mediaImage->mPlane[mediaImage->V].mColInc = 1;
- mediaImage->mPlane[mediaImage->V].mRowInc = mStride / 2;
- mediaImage->mPlane[mediaImage->V].mHorizSubsampling = 2;
- mediaImage->mPlane[mediaImage->V].mVertSubsampling = 2;
- break;
-
- case COLOR_FormatYUV420SemiPlanar:
- case COLOR_FormatYUV420PackedSemiPlanar:
- mediaImage->mPlane[mediaImage->Y].mOffset = 0;
- mediaImage->mPlane[mediaImage->Y].mColInc = 1;
- mediaImage->mPlane[mediaImage->Y].mRowInc = mStride;
- mediaImage->mPlane[mediaImage->Y].mHorizSubsampling = 1;
- mediaImage->mPlane[mediaImage->Y].mVertSubsampling = 1;
-
- mediaImage->mPlane[mediaImage->U].mOffset = mStride * mVStride;
- mediaImage->mPlane[mediaImage->U].mColInc = 2;
- mediaImage->mPlane[mediaImage->U].mRowInc = mStride;
- mediaImage->mPlane[mediaImage->U].mHorizSubsampling = 2;
- mediaImage->mPlane[mediaImage->U].mVertSubsampling = 2;
-
- mediaImage->mPlane[mediaImage->V].mOffset = mStride * mVStride + 1;
- mediaImage->mPlane[mediaImage->V].mColInc = 2;
- mediaImage->mPlane[mediaImage->V].mRowInc = mStride;
- mediaImage->mPlane[mediaImage->V].mHorizSubsampling = 2;
- mediaImage->mPlane[mediaImage->V].mVertSubsampling = 2;
- break;
-
- default:
- ALOGD("Converter: incompactible color format (%d) for YUV layout", mColorFormat);
- mInitCheck = BAD_VALUE;
- return;
- }
- break;
- case C2PlanarLayout::TYPE_YUVA:
- mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_YUVA;
- // We don't have an SDK YUVA format
- ALOGD("Converter: incompactible color format (%d) for YUVA layout", mColorFormat);
- mInitCheck = BAD_VALUE;
- return;
- case C2PlanarLayout::TYPE_RGB:
- mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGB;
- switch (mColorFormat) {
- // TODO media image
- case COLOR_FormatRGBFlexible:
- case COLOR_Format24bitBGR888:
- case COLOR_Format24bitRGB888:
- break;
- default:
- ALOGD("Converter: incompactible color format (%d) for RGB layout", mColorFormat);
- mInitCheck = BAD_VALUE;
- return;
- }
- if (layout.numPlanes != 3) {
- ALOGD("Converter: %d planes for RGB layout", layout.numPlanes);
- mInitCheck = BAD_VALUE;
- return;
- }
- break;
- case C2PlanarLayout::TYPE_RGBA:
- mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_RGBA;
- switch (mColorFormat) {
- // TODO media image
- case COLOR_FormatRGBAFlexible:
- case COLOR_Format32bitABGR8888:
- case COLOR_Format32bitARGB8888:
- case COLOR_Format32bitBGRA8888:
- break;
- default:
- ALOGD("Incompactible color format (%d) for RGBA layout", mColorFormat);
- mInitCheck = BAD_VALUE;
- return;
- }
- if (layout.numPlanes != 4) {
- ALOGD("Converter: %d planes for RGBA layout", layout.numPlanes);
- mInitCheck = BAD_VALUE;
- return;
- }
- break;
- default:
- mediaImage->mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
- ALOGD("Unknown layout");
- mInitCheck = BAD_VALUE;
- return;
- }
- mediaImage->mNumPlanes = layout.numPlanes;
- mediaImage->mWidth = mWidth;
- mediaImage->mHeight = mHeight;
- mediaImage->mBitDepth = bitDepth;
- mediaImage->mBitDepthAllocated = mAllocatedDepth;
-
- uint32_t bufferSize = 0;
- for (uint32_t i = 0; i < layout.numPlanes; ++i) {
- const C2PlaneInfo &plane = layout.planes[i];
- if (plane.allocatedDepth < plane.bitDepth
- || plane.rightShift != plane.allocatedDepth - plane.bitDepth) {
- ALOGD("rightShift value of %u unsupported", plane.rightShift);
- mInitCheck = BAD_VALUE;
- return;
- }
- if (plane.allocatedDepth > 8 && plane.endianness != C2PlaneInfo::NATIVE) {
- ALOGD("endianness value of %u unsupported", plane.endianness);
- mInitCheck = BAD_VALUE;
- return;
- }
- if (plane.allocatedDepth != mAllocatedDepth || plane.bitDepth != bitDepth) {
- ALOGV("different allocatedDepth/bitDepth per plane unsupported");
- mInitCheck = BAD_VALUE;
- return;
- }
- bufferSize += mStride * mVStride
- / plane.rowSampling / plane.colSampling;
- }
-
- mBackBufferSize = bufferSize;
- mInitCheck = OK;
- }
-
- status_t initCheck() const { return mInitCheck; }
-
- uint32_t backBufferSize() const { return mBackBufferSize; }
-
- /**
- * Wrap C2GraphicView using a MediaImage2. Note that if not wrapped, the content is not mapped
- * in this function --- the caller should use CopyGraphicView2MediaImage() function to copy the
- * data into a backing buffer explicitly.
- *
- * \return media buffer. This is null if wrapping failed.
- */
- sp<ABuffer> wrap() const {
- if (mBackBuffer == nullptr) {
- return mWrapped;
- }
- return nullptr;
- }
-
- bool setBackBuffer(const sp<ABuffer> &backBuffer) {
- if (backBuffer->capacity() < mBackBufferSize) {
- return false;
- }
- backBuffer->setRange(0, mBackBufferSize);
- mBackBuffer = backBuffer;
- return true;
- }
-
- /**
- * Copy C2GraphicView to MediaImage2.
- */
- status_t copyToMediaImage() {
- if (mInitCheck != OK) {
- return mInitCheck;
- }
- return ImageCopy(mBackBuffer->base(), getMediaImage(), mView);
- }
-
- const sp<ABuffer> &imageData() const { return mMediaImage; }
-
-private:
- status_t mInitCheck;
-
- const C2GraphicView mView;
- uint32_t mWidth;
- uint32_t mHeight;
- int32_t mColorFormat; ///< SDK color format for MediaImage
- sp<ABuffer> mWrapped; ///< wrapped buffer (if we can map C2Buffer to an ABuffer)
- uint32_t mAllocatedDepth;
- uint32_t mBackBufferSize;
- sp<ABuffer> mMediaImage;
- std::function<sp<ABuffer>(size_t)> mAlloc;
-
- sp<ABuffer> mBackBuffer; ///< backing buffer if we have to copy C2Buffer <=> ABuffer
-
- MediaImage2 *getMediaImage() {
- return (MediaImage2 *)mMediaImage->base();
- }
-};
-
-} // namespace
-
-// GraphicBlockBuffer
-
-// static
-sp<GraphicBlockBuffer> GraphicBlockBuffer::Allocate(
- const sp<AMessage> &format,
- const std::shared_ptr<C2GraphicBlock> &block,
- std::function<sp<ABuffer>(size_t)> alloc) {
- C2GraphicView view(block->map().get());
- if (view.error() != C2_OK) {
- ALOGD("C2GraphicBlock::map failed: %d", view.error());
- return nullptr;
- }
-
- int32_t colorFormat = COLOR_FormatYUV420Flexible;
- (void)format->findInt32("color-format", &colorFormat);
-
- GraphicView2MediaImageConverter converter(view, colorFormat);
- if (converter.initCheck() != OK) {
- ALOGD("Converter init failed: %d", converter.initCheck());
- return nullptr;
- }
- bool wrapped = true;
- sp<ABuffer> buffer = converter.wrap();
- if (buffer == nullptr) {
- buffer = alloc(converter.backBufferSize());
- if (!converter.setBackBuffer(buffer)) {
- ALOGD("Converter failed to set back buffer");
- return nullptr;
- }
- wrapped = false;
- }
- return new GraphicBlockBuffer(
- format,
- buffer,
- std::move(view),
- block,
- converter.imageData(),
- wrapped);
-}
-
-GraphicBlockBuffer::GraphicBlockBuffer(
- const sp<AMessage> &format,
- const sp<ABuffer> &buffer,
- C2GraphicView &&view,
- const std::shared_ptr<C2GraphicBlock> &block,
- const sp<ABuffer> &imageData,
- bool wrapped)
- : Codec2Buffer(format, buffer),
- mView(view),
- mBlock(block),
- mImageData(imageData),
- mWrapped(wrapped) {
- setImageData(imageData);
-}
-
-std::shared_ptr<C2Buffer> GraphicBlockBuffer::asC2Buffer() {
- uint32_t width = mView.width();
- uint32_t height = mView.height();
- if (!mWrapped) {
- (void)ImageCopy(mView, base(), imageData());
- }
- return C2Buffer::CreateGraphicBuffer(
- mBlock->share(C2Rect(width, height), C2Fence()));
-}
-
-// GraphicMetadataBuffer
-GraphicMetadataBuffer::GraphicMetadataBuffer(
- const sp<AMessage> &format,
- const std::shared_ptr<C2Allocator> &alloc)
- : Codec2Buffer(format, new ABuffer(sizeof(VideoNativeMetadata))),
- mAlloc(alloc) {
- ((VideoNativeMetadata *)base())->pBuffer = nullptr;
-}
-
-std::shared_ptr<C2Buffer> GraphicMetadataBuffer::asC2Buffer() {
-#ifndef __LP64__
- VideoNativeMetadata *meta = (VideoNativeMetadata *)base();
- ANativeWindowBuffer *buffer = (ANativeWindowBuffer *)meta->pBuffer;
- if (buffer == nullptr) {
- ALOGD("VideoNativeMetadata contains null buffer");
- return nullptr;
- }
-
- ALOGV("VideoNativeMetadata: %dx%d", buffer->width, buffer->height);
- C2Handle *handle = WrapNativeCodec2GrallocHandle(
- buffer->handle,
- buffer->width,
- buffer->height,
- buffer->format,
- buffer->usage,
- buffer->stride);
- std::shared_ptr<C2GraphicAllocation> alloc;
- c2_status_t err = mAlloc->priorGraphicAllocation(handle, &alloc);
- if (err != C2_OK) {
- ALOGD("Failed to wrap VideoNativeMetadata into C2GraphicAllocation");
- return nullptr;
- }
- std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(alloc);
-
- meta->pBuffer = 0;
- // TODO: fence
- return C2Buffer::CreateGraphicBuffer(
- block->share(C2Rect(buffer->width, buffer->height), C2Fence()));
-#else
- ALOGE("GraphicMetadataBuffer does not work on 64-bit arch");
- return nullptr;
-#endif
-}
-
-// ConstGraphicBlockBuffer
-
-// static
-sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::Allocate(
- const sp<AMessage> &format,
- const std::shared_ptr<C2Buffer> &buffer,
- std::function<sp<ABuffer>(size_t)> alloc) {
- if (!buffer
- || buffer->data().type() != C2BufferData::GRAPHIC
- || buffer->data().graphicBlocks().size() != 1u) {
- ALOGD("C2Buffer precond fail");
- return nullptr;
- }
- std::unique_ptr<const C2GraphicView> view(std::make_unique<const C2GraphicView>(
- buffer->data().graphicBlocks()[0].map().get()));
- std::unique_ptr<const C2GraphicView> holder;
-
- int32_t colorFormat = COLOR_FormatYUV420Flexible;
- (void)format->findInt32("color-format", &colorFormat);
-
- GraphicView2MediaImageConverter converter(*view, colorFormat);
- if (converter.initCheck() != OK) {
- ALOGD("Converter init failed: %d", converter.initCheck());
- return nullptr;
- }
- bool wrapped = true;
- sp<ABuffer> aBuffer = converter.wrap();
- if (aBuffer == nullptr) {
- aBuffer = alloc(converter.backBufferSize());
- if (!converter.setBackBuffer(aBuffer)) {
- ALOGD("Converter failed to set back buffer");
- return nullptr;
- }
- wrapped = false;
- converter.copyToMediaImage();
- // We don't need the view.
- holder = std::move(view);
- }
- return new ConstGraphicBlockBuffer(
- format,
- aBuffer,
- std::move(view),
- buffer,
- converter.imageData(),
- wrapped);
-}
-
-// static
-sp<ConstGraphicBlockBuffer> ConstGraphicBlockBuffer::AllocateEmpty(
- const sp<AMessage> &format,
- std::function<sp<ABuffer>(size_t)> alloc) {
- int32_t width, height;
- if (!format->findInt32("width", &width)
- || !format->findInt32("height", &height)) {
- ALOGD("format had no width / height");
- return nullptr;
- }
- sp<ABuffer> aBuffer(alloc(width * height * 4));
- return new ConstGraphicBlockBuffer(
- format,
- aBuffer,
- nullptr,
- nullptr,
- nullptr,
- false);
-}
-
-ConstGraphicBlockBuffer::ConstGraphicBlockBuffer(
- const sp<AMessage> &format,
- const sp<ABuffer> &aBuffer,
- std::unique_ptr<const C2GraphicView> &&view,
- const std::shared_ptr<C2Buffer> &buffer,
- const sp<ABuffer> &imageData,
- bool wrapped)
- : Codec2Buffer(format, aBuffer),
- mView(std::move(view)),
- mBufferRef(buffer),
- mWrapped(wrapped) {
- if (imageData != nullptr) {
- setImageData(imageData);
- }
-}
-
-std::shared_ptr<C2Buffer> ConstGraphicBlockBuffer::asC2Buffer() {
- mView.reset();
- return std::move(mBufferRef);
-}
-
-bool ConstGraphicBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
- if (mWrapped || mBufferRef) {
- ALOGD("ConstGraphicBlockBuffer::canCopy: %swrapped ; buffer ref %s",
- mWrapped ? "" : "not ", mBufferRef ? "exists" : "doesn't exist");
- return false;
- }
- if (!buffer) {
- // Nothing to copy, so we can copy by doing nothing.
- return true;
- }
- if (buffer->data().type() != C2BufferData::GRAPHIC) {
- ALOGD("ConstGraphicBlockBuffer::canCopy: buffer precondition unsatisfied");
- return false;
- }
- if (buffer->data().graphicBlocks().size() == 0) {
- return true;
- } else if (buffer->data().graphicBlocks().size() != 1u) {
- ALOGD("ConstGraphicBlockBuffer::canCopy: too many blocks");
- return false;
- }
-
- int32_t colorFormat = COLOR_FormatYUV420Flexible;
- // FIXME: format() is not const, but we cannot change it, so do a const cast here
- const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
-
- GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
- if (converter.initCheck() != OK) {
- ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
- return false;
- }
- if (converter.backBufferSize() > capacity()) {
- ALOGD("ConstGraphicBlockBuffer::canCopy: insufficient capacity: req %u has %zu",
- converter.backBufferSize(), capacity());
- return false;
- }
- return true;
-}
-
-bool ConstGraphicBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) {
- if (!buffer || buffer->data().graphicBlocks().size() == 0) {
- setRange(0, 0);
- return true;
- }
- int32_t colorFormat = COLOR_FormatYUV420Flexible;
- format()->findInt32("color-format", &colorFormat);
-
- GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
- if (converter.initCheck() != OK) {
- ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
- return false;
- }
- sp<ABuffer> aBuffer = new ABuffer(base(), capacity());
- if (!converter.setBackBuffer(aBuffer)) {
- ALOGD("ConstGraphicBlockBuffer::copy: set back buffer failed");
- return false;
- }
- converter.copyToMediaImage();
- setImageData(converter.imageData());
- mBufferRef = buffer;
- return true;
-}
-
-// EncryptedLinearBlockBuffer
-
-EncryptedLinearBlockBuffer::EncryptedLinearBlockBuffer(
- const sp<AMessage> &format,
- const std::shared_ptr<C2LinearBlock> &block,
- const sp<IMemory> &memory,
- int32_t heapSeqNum)
- : Codec2Buffer(format, new ABuffer(memory->pointer(), memory->size())),
- mBlock(block),
- mMemory(memory),
- mHeapSeqNum(heapSeqNum) {
-}
-
-std::shared_ptr<C2Buffer> EncryptedLinearBlockBuffer::asC2Buffer() {
- return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence()));
-}
-
-void EncryptedLinearBlockBuffer::fillSourceBuffer(
- ICrypto::SourceBuffer *source) {
- source->mSharedMemory = mMemory;
- source->mHeapSeqNum = mHeapSeqNum;
-}
-
-void EncryptedLinearBlockBuffer::fillSourceBuffer(
- hardware::cas::native::V1_0::SharedBuffer *source) {
- ssize_t offset;
- size_t size;
-
- mHidlMemory = hardware::fromHeap(mMemory->getMemory(&offset, &size));
- source->heapBase = *mHidlMemory;
- source->offset = offset;
- source->size = size;
-}
-
-bool EncryptedLinearBlockBuffer::copyDecryptedContent(
- const sp<IMemory> &decrypted, size_t length) {
- C2WriteView view = mBlock->map().get();
- if (view.error() != C2_OK) {
- return false;
- }
- if (view.size() < length) {
- return false;
- }
- memcpy(view.data(), decrypted->pointer(), length);
- return true;
-}
-
-bool EncryptedLinearBlockBuffer::copyDecryptedContentFromMemory(size_t length) {
- return copyDecryptedContent(mMemory, length);
-}
-
-native_handle_t *EncryptedLinearBlockBuffer::handle() const {
- return const_cast<native_handle_t *>(mBlock->handle());
-}
-
-} // namespace android
diff --git a/media/sfplugin/Codec2Buffer.h b/media/sfplugin/Codec2Buffer.h
deleted file mode 100644
index d5d41a4..0000000
--- a/media/sfplugin/Codec2Buffer.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright 2017, 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.
- */
-
-#ifndef CODEC2_BUFFER_H_
-
-#define CODEC2_BUFFER_H_
-
-#include <C2Buffer.h>
-
-#include <android/hardware/cas/native/1.0/types.h>
-#include <binder/IMemory.h>
-#include <media/hardware/VideoAPI.h>
-#include <media/MediaCodecBuffer.h>
-#include <mediadrm/ICrypto.h>
-
-namespace android {
-
-/**
- * Copies a graphic view into a media image.
- *
- * \param imgBase base of MediaImage
- * \param img MediaImage data
- * \param view graphic view
- *
- * \return OK on success
- */
-status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
-
-/**
- * Copies a media image into a graphic view.
- *
- * \param view graphic view
- * \param imgBase base of MediaImage
- * \param img MediaImage data
- *
- * \return OK on success
- */
-status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
-
-class Codec2Buffer : public MediaCodecBuffer {
-public:
- using MediaCodecBuffer::MediaCodecBuffer;
- ~Codec2Buffer() override = default;
-
- /**
- * \return C2Buffer object represents this buffer.
- */
- virtual std::shared_ptr<C2Buffer> asC2Buffer() = 0;
-
- /**
- * Test if we can copy the content of |buffer| into this object.
- *
- * \param buffer C2Buffer object to copy.
- * \return true if the content of buffer can be copied over to this buffer
- * false otherwise.
- */
- virtual bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
- (void)buffer;
- return false;
- }
-
- /**
- * Copy the content of |buffer| into this object. This method assumes that
- * canCopy() check already passed.
- *
- * \param buffer C2Buffer object to copy.
- * \return true if successful
- * false otherwise.
- */
- virtual bool copy(const std::shared_ptr<C2Buffer> &buffer) {
- (void)buffer;
- return false;
- }
-
-protected:
- /**
- * canCopy() implementation for linear buffers.
- */
- bool canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const;
-
- /**
- * copy() implementation for linear buffers.
- */
- bool copyLinear(const std::shared_ptr<C2Buffer> &buffer);
-
- /**
- * sets MediaImage data for flexible graphic buffers
- */
- void setImageData(const sp<ABuffer> &imageData);
-};
-
-/**
- * MediaCodecBuffer implementation on top of local linear buffer. This cannot
- * cross process boundary so asC2Buffer() returns only nullptr.
- */
-class LocalLinearBuffer : public Codec2Buffer {
-public:
- using Codec2Buffer::Codec2Buffer;
-
- std::shared_ptr<C2Buffer> asC2Buffer() override { return nullptr; }
- bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
- bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
-};
-
-/**
- * MediaCodecBuffer implementation to be used only as a dummy wrapper around a
- * C2Buffer object.
- */
-class DummyContainerBuffer : public Codec2Buffer {
-public:
- DummyContainerBuffer(
- const sp<AMessage> &format,
- const std::shared_ptr<C2Buffer> &buffer = nullptr);
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
- bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
- bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
-
-private:
- std::shared_ptr<C2Buffer> mBufferRef;
-};
-
-/**
- * MediaCodecBuffer implementation wraps around C2LinearBlock.
- */
-class LinearBlockBuffer : public Codec2Buffer {
-public:
- /**
- * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- * \param block C2LinearBlock object to wrap around.
- * \return LinearBlockBuffer object with writable mapping.
- * nullptr if unsuccessful.
- */
- static sp<LinearBlockBuffer> Allocate(
- const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);
-
- virtual ~LinearBlockBuffer() = default;
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
- bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
- bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
-
-private:
- LinearBlockBuffer(
- const sp<AMessage> &format,
- C2WriteView &&writeView,
- const std::shared_ptr<C2LinearBlock> &block);
- LinearBlockBuffer() = delete;
-
- C2WriteView mWriteView;
- std::shared_ptr<C2LinearBlock> mBlock;
-};
-
-/**
- * MediaCodecBuffer implementation wraps around C2ConstLinearBlock.
- */
-class ConstLinearBlockBuffer : public Codec2Buffer {
-public:
- /**
- * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- * \param buffer linear C2Buffer object to wrap around.
- * \return ConstLinearBlockBuffer object with readable mapping.
- * nullptr if unsuccessful.
- */
- static sp<ConstLinearBlockBuffer> Allocate(
- const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer);
-
- virtual ~ConstLinearBlockBuffer() = default;
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
-
-private:
- ConstLinearBlockBuffer(
- const sp<AMessage> &format,
- C2ReadView &&readView,
- const std::shared_ptr<C2Buffer> &buffer);
- ConstLinearBlockBuffer() = delete;
-
- C2ReadView mReadView;
- std::shared_ptr<C2Buffer> mBufferRef;
-};
-
-/**
- * MediaCodecBuffer implementation wraps around C2GraphicBlock.
- *
- * This object exposes the underlying bits via accessor APIs and "image-data"
- * metadata, created automatically at allocation time.
- */
-class GraphicBlockBuffer : public Codec2Buffer {
-public:
- /**
- * Allocate a new GraphicBlockBuffer wrapping around C2GraphicBlock object.
- * If |block| is not in good color formats, it allocates YV12 local buffer
- * and copies the content over at asC2Buffer().
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- * \param block C2GraphicBlock object to wrap around.
- * \param alloc a function to allocate backing ABuffer if needed.
- * \return GraphicBlockBuffer object with writable mapping.
- * nullptr if unsuccessful.
- */
- static sp<GraphicBlockBuffer> Allocate(
- const sp<AMessage> &format,
- const std::shared_ptr<C2GraphicBlock> &block,
- std::function<sp<ABuffer>(size_t)> alloc);
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
-
- virtual ~GraphicBlockBuffer() = default;
-
-private:
- GraphicBlockBuffer(
- const sp<AMessage> &format,
- const sp<ABuffer> &buffer,
- C2GraphicView &&view,
- const std::shared_ptr<C2GraphicBlock> &block,
- const sp<ABuffer> &imageData,
- bool wrapped);
- GraphicBlockBuffer() = delete;
-
- inline MediaImage2 *imageData() { return (MediaImage2 *)mImageData->data(); }
-
- C2GraphicView mView;
- std::shared_ptr<C2GraphicBlock> mBlock;
- sp<ABuffer> mImageData;
- const bool mWrapped;
-};
-
-/**
- * MediaCodecBuffer implementation wraps around VideoNativeMetadata.
- */
-class GraphicMetadataBuffer : public Codec2Buffer {
-public:
- /**
- * Construct a new GraphicMetadataBuffer with local linear buffer for
- * VideoNativeMetadata.
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- */
- GraphicMetadataBuffer(
- const sp<AMessage> &format, const std::shared_ptr<C2Allocator> &alloc);
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
-
- virtual ~GraphicMetadataBuffer() = default;
-
-private:
- GraphicMetadataBuffer() = delete;
-
- std::shared_ptr<C2Allocator> mAlloc;
-};
-
-/**
- * MediaCodecBuffer implementation wraps around graphic C2Buffer object.
- *
- * This object exposes the underlying bits via accessor APIs and "image-data"
- * metadata, created automatically at allocation time.
- */
-class ConstGraphicBlockBuffer : public Codec2Buffer {
-public:
- /**
- * Allocate a new ConstGraphicBlockBuffer wrapping around C2Buffer object.
- * If |buffer| is not in good color formats, it allocates YV12 local buffer
- * and copies the content of |buffer| over to expose.
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- * \param buffer graphic C2Buffer object to wrap around.
- * \param alloc a function to allocate backing ABuffer if needed.
- * \return ConstGraphicBlockBuffer object with readable mapping.
- * nullptr if unsuccessful.
- */
- static sp<ConstGraphicBlockBuffer> Allocate(
- const sp<AMessage> &format,
- const std::shared_ptr<C2Buffer> &buffer,
- std::function<sp<ABuffer>(size_t)> alloc);
-
- /**
- * Allocate a new ConstGraphicBlockBuffer which allocates YV12 local buffer
- * and copies the content of |buffer| over to expose.
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- * \param alloc a function to allocate backing ABuffer if needed.
- * \return ConstGraphicBlockBuffer object with no wrapping buffer.
- */
- static sp<ConstGraphicBlockBuffer> AllocateEmpty(
- const sp<AMessage> &format,
- std::function<sp<ABuffer>(size_t)> alloc);
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
- bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
- bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
-
- virtual ~ConstGraphicBlockBuffer() = default;
-
-private:
- ConstGraphicBlockBuffer(
- const sp<AMessage> &format,
- const sp<ABuffer> &aBuffer,
- std::unique_ptr<const C2GraphicView> &&view,
- const std::shared_ptr<C2Buffer> &buffer,
- const sp<ABuffer> &imageData,
- bool wrapped);
- ConstGraphicBlockBuffer() = delete;
-
- sp<ABuffer> mImageData;
- std::unique_ptr<const C2GraphicView> mView;
- std::shared_ptr<C2Buffer> mBufferRef;
- const bool mWrapped;
-};
-
-/**
- * MediaCodecBuffer implementation wraps around C2LinearBlock for component
- * and IMemory for client. Underlying C2LinearBlock won't be mapped for secure
- * usecases..
- */
-class EncryptedLinearBlockBuffer : public Codec2Buffer {
-public:
- /**
- * Construct a new EncryptedLinearBufferBlock wrapping around C2LinearBlock
- * object and writable IMemory region.
- *
- * \param format mandatory buffer format for MediaCodecBuffer
- * \param block C2LinearBlock object to wrap around.
- * \param memory IMemory object to store encrypted content.
- * \param heapSeqNum Heap sequence number from ICrypto; -1 if N/A
- */
- EncryptedLinearBlockBuffer(
- const sp<AMessage> &format,
- const std::shared_ptr<C2LinearBlock> &block,
- const sp<IMemory> &memory,
- int32_t heapSeqNum = -1);
- EncryptedLinearBlockBuffer() = delete;
-
- virtual ~EncryptedLinearBlockBuffer() = default;
-
- std::shared_ptr<C2Buffer> asC2Buffer() override;
-
- /**
- * Fill the source buffer structure with appropriate value based on
- * internal IMemory object.
- *
- * \param source source buffer structure to fill.
- */
- void fillSourceBuffer(ICrypto::SourceBuffer *source);
- void fillSourceBuffer(
- hardware::cas::native::V1_0::SharedBuffer *source);
-
- /**
- * Copy the content of |decrypted| into C2LinearBlock inside. This shall
- * only be called in non-secure usecases.
- *
- * \param decrypted decrypted content to copy from.
- * \param length length of the content
- * \return true if successful
- * false otherwise.
- */
- bool copyDecryptedContent(const sp<IMemory> &decrypted, size_t length);
-
- /**
- * Copy the content of internal IMemory object into C2LinearBlock inside.
- * This shall only be called in non-secure usecases.
- *
- * \param length length of the content
- * \return true if successful
- * false otherwise.
- */
- bool copyDecryptedContentFromMemory(size_t length);
-
- /**
- * Return native handle of secure buffer understood by ICrypto.
- *
- * \return secure buffer handle
- */
- native_handle_t *handle() const;
-
-private:
-
- std::shared_ptr<C2LinearBlock> mBlock;
- sp<IMemory> mMemory;
- sp<hardware::HidlMemory> mHidlMemory;
- int32_t mHeapSeqNum;
-};
-
-} // namespace android
-
-#endif // CODEC2_BUFFER_H_
diff --git a/media/sfplugin/Codec2InfoBuilder.cpp b/media/sfplugin/Codec2InfoBuilder.cpp
deleted file mode 100644
index 4a6d672..0000000
--- a/media/sfplugin/Codec2InfoBuilder.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (C) 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 "Codec2InfoBuilder"
-#include <log/log.h>
-
-#include <strings.h>
-
-#include <C2Component.h>
-#include <C2Config.h>
-#include <C2Debug.h>
-#include <C2PlatformSupport.h>
-#include <Codec2Mapper.h>
-
-#include <OMX_Audio.h>
-#include <OMX_AudioExt.h>
-#include <OMX_IndexExt.h>
-#include <OMX_Types.h>
-#include <OMX_Video.h>
-#include <OMX_VideoExt.h>
-#include <OMX_AsString.h>
-
-#include <android/hardware/media/omx/1.0/IOmx.h>
-#include <android/hardware/media/omx/1.0/IOmxObserver.h>
-#include <android/hardware/media/omx/1.0/IOmxNode.h>
-#include <android/hardware/media/omx/1.0/types.h>
-
-#include <android-base/properties.h>
-#include <codec2/hidl/client.h>
-#include <cutils/native_handle.h>
-#include <media/omx/1.0/WOmxNode.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/foundation/ALookup.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-#include <media/stagefright/omx/OMXUtils.h>
-#include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
-
-#include "Codec2InfoBuilder.h"
-
-namespace android {
-
-using Traits = C2Component::Traits;
-
-namespace /* unnamed */ {
-
-bool hasPrefix(const std::string& s, const char* prefix) {
- size_t prefixLen = strlen(prefix);
- return s.compare(0, prefixLen, prefix) == 0;
-}
-
-bool hasSuffix(const std::string& s, const char* suffix) {
- size_t suffixLen = strlen(suffix);
- return suffixLen > s.size() ? false :
- s.compare(s.size() - suffixLen, suffixLen, suffix) == 0;
-}
-
-// Constants from ACodec
-constexpr OMX_U32 kPortIndexInput = 0;
-constexpr OMX_U32 kPortIndexOutput = 1;
-constexpr OMX_U32 kMaxIndicesToCheck = 32;
-
-status_t queryOmxCapabilities(
- const char* name, const char* mediaType, bool isEncoder,
- MediaCodecInfo::CapabilitiesWriter* caps) {
-
- const char *role = GetComponentRole(isEncoder, mediaType);
- if (role == nullptr) {
- return BAD_VALUE;
- }
-
- using namespace ::android::hardware::media::omx::V1_0;
- using ::android::hardware::Return;
- using ::android::hardware::Void;
- using ::android::hardware::hidl_vec;
- using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
-
- sp<IOmx> omx = IOmx::getService();
- if (!omx) {
- ALOGW("Could not obtain IOmx service.");
- return NO_INIT;
- }
-
- struct Observer : IOmxObserver {
- virtual Return<void> onMessages(const hidl_vec<Message>&) override {
- return Void();
- }
- };
-
- sp<Observer> observer = new Observer();
- Status status;
- sp<IOmxNode> tOmxNode;
- Return<void> transStatus = omx->allocateNode(
- name, observer,
- [&status, &tOmxNode](Status s, const sp<IOmxNode>& n) {
- status = s;
- tOmxNode = n;
- });
- if (!transStatus.isOk()) {
- ALOGW("IOmx::allocateNode -- transaction failed.");
- return NO_INIT;
- }
- if (status != Status::OK) {
- ALOGW("IOmx::allocateNode -- error returned: %d.",
- static_cast<int>(status));
- return NO_INIT;
- }
-
- sp<LWOmxNode> omxNode = new LWOmxNode(tOmxNode);
-
- status_t err = SetComponentRole(omxNode, role);
- if (err != OK) {
- omxNode->freeNode();
- ALOGW("Failed to SetComponentRole: component = %s, role = %s.",
- name, role);
- return err;
- }
-
- bool isVideo = hasPrefix(mediaType, "video/") == 0;
- bool isImage = hasPrefix(mediaType, "image/") == 0;
-
- if (isVideo || isImage) {
- OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
- InitOMXParams(&param);
- param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
-
- for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
- param.nProfileIndex = index;
- status_t err = omxNode->getParameter(
- OMX_IndexParamVideoProfileLevelQuerySupported,
- &param, sizeof(param));
- if (err != OK) {
- break;
- }
- caps->addProfileLevel(param.eProfile, param.eLevel);
-
- // AVC components may not list the constrained profiles explicitly, but
- // decoders that support a profile also support its constrained version.
- // Encoders must explicitly support constrained profiles.
- if (!isEncoder && strcasecmp(mediaType, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
- if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
- caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
- } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
- caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
- }
- }
-
- if (index == kMaxIndicesToCheck) {
- ALOGW("[%s] stopping checking profiles after %u: %x/%x",
- name, index,
- param.eProfile, param.eLevel);
- }
- }
-
- // Color format query
- // return colors in the order reported by the OMX component
- // prefix "flexible" standard ones with the flexible equivalent
- OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
- InitOMXParams(&portFormat);
- portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
- for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
- portFormat.nIndex = index;
- status_t err = omxNode->getParameter(
- OMX_IndexParamVideoPortFormat,
- &portFormat, sizeof(portFormat));
- if (err != OK) {
- break;
- }
-
- OMX_U32 flexibleEquivalent;
- if (IsFlexibleColorFormat(
- omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
- &flexibleEquivalent)) {
- caps->addColorFormat(flexibleEquivalent);
- }
- caps->addColorFormat(portFormat.eColorFormat);
-
- if (index == kMaxIndicesToCheck) {
- ALOGW("[%s] stopping checking formats after %u: %s(%x)",
- name, index,
- asString(portFormat.eColorFormat), portFormat.eColorFormat);
- }
- }
- } else if (strcasecmp(mediaType, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
- // More audio codecs if they have profiles.
- OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
- InitOMXParams(&param);
- param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
- for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
- param.nProfileIndex = index;
- status_t err = omxNode->getParameter(
- (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
- &param, sizeof(param));
- if (err != OK) {
- break;
- }
- // For audio, level is ignored.
- caps->addProfileLevel(param.eProfile, 0 /* level */);
-
- if (index == kMaxIndicesToCheck) {
- ALOGW("[%s] stopping checking profiles after %u: %x",
- name, index,
- param.eProfile);
- }
- }
-
- // NOTE: Without Android extensions, OMX does not provide a way to query
- // AAC profile support
- if (param.nProfileIndex == 0) {
- ALOGW("component %s doesn't support profile query.", name);
- }
- }
-
- if (isVideo && !isEncoder) {
- native_handle_t *sidebandHandle = nullptr;
- if (omxNode->configureVideoTunnelMode(
- kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
- // tunneled playback includes adaptive playback
- caps->addDetail(MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK, 1);
- caps->addDetail(MediaCodecInfo::Capabilities::FEATURE_TUNNELED_PLAYBACK, 1);
- } else if (omxNode->setPortMode(
- kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
- omxNode->prepareForAdaptivePlayback(
- kPortIndexOutput, OMX_TRUE,
- 1280 /* width */, 720 /* height */) == OK) {
- caps->addDetail(MediaCodecInfo::Capabilities::FEATURE_ADAPTIVE_PLAYBACK, 1);
- }
- }
-
- if (isVideo && isEncoder) {
- OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
- InitOMXParams(&params);
- params.nPortIndex = kPortIndexOutput;
- // TODO: should we verify if fallback is supported?
- if (omxNode->getConfig(
- (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
- &params, sizeof(params)) == OK) {
- caps->addDetail(MediaCodecInfo::Capabilities::FEATURE_INTRA_REFRESH, 1);
- }
- }
-
- omxNode->freeNode();
- return OK;
-}
-
-void buildOmxInfo(const MediaCodecsXmlParser& parser,
- MediaCodecListWriter* writer) {
- uint32_t omxRank = ::android::base::GetUintProperty(
- "debug.stagefright.omx_default_rank", uint32_t(0x100));
- for (const MediaCodecsXmlParser::Codec& codec : parser.getCodecMap()) {
- const std::string &name = codec.first;
- if (!hasPrefix(codec.first, "OMX.")) {
- continue;
- }
- const MediaCodecsXmlParser::CodecProperties &properties = codec.second;
- bool encoder = properties.isEncoder;
- std::unique_ptr<MediaCodecInfoWriter> info =
- writer->addMediaCodecInfo();
- info->setName(name.c_str());
- info->setOwner("default");
- typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs = 0;
- if (encoder) {
- attrs |= MediaCodecInfo::kFlagIsEncoder;
- }
- // NOTE: we don't support software-only codecs in OMX
- if (!hasPrefix(name, "OMX.google.")) {
- attrs |= MediaCodecInfo::kFlagIsVendor;
- if (properties.quirkSet.find("attribute::software-codec")
- == properties.quirkSet.end()) {
- attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
- }
- }
- info->setAttributes(attrs);
- info->setRank(omxRank);
- // OMX components don't have aliases
- for (const MediaCodecsXmlParser::Type &type : properties.typeMap) {
- const std::string &mediaType = type.first;
- std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
- info->addMediaType(mediaType.c_str());
- const MediaCodecsXmlParser::AttributeMap &attrMap = type.second;
- for (const MediaCodecsXmlParser::Attribute& attr : attrMap) {
- const std::string &key = attr.first;
- const std::string &value = attr.second;
- if (hasPrefix(key, "feature-") &&
- !hasPrefix(key, "feature-bitrate-modes")) {
- caps->addDetail(key.c_str(), hasPrefix(value, "1") ? 1 : 0);
- } else {
- caps->addDetail(key.c_str(), value.c_str());
- }
- }
- status_t err = queryOmxCapabilities(
- name.c_str(),
- mediaType.c_str(),
- encoder,
- caps.get());
- if (err != OK) {
- ALOGI("Failed to query capabilities for %s (media type: %s). Error: %d",
- name.c_str(),
- mediaType.c_str(),
- static_cast<int>(err));
- }
- }
- }
-}
-
-} // unnamed namespace
-
-status_t Codec2InfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {
- // TODO: Remove run-time configurations once all codecs are working
- // properly. (Assume "full" behavior eventually.)
- //
- // debug.stagefright.ccodec supports 5 values.
- // 0 - Only OMX components are available.
- // 1 - Audio decoders and encoders with prefix "c2.android." are available
- // and ranked first.
- // All other components with prefix "c2.android." are available with
- // their normal ranks.
- // Components with prefix "c2.vda." are available with their normal
- // ranks.
- // All other components with suffix ".avc.decoder" or ".avc.encoder"
- // are available but ranked last.
- // 2 - Components with prefix "c2.android." are available and ranked
- // first.
- // Components with prefix "c2.vda." are available with their normal
- // ranks.
- // All other components with suffix ".avc.decoder" or ".avc.encoder"
- // are available but ranked last.
- // 3 - Components with prefix "c2.android." are available and ranked
- // first.
- // All other components are available with their normal ranks.
- // 4 - All components are available with their normal ranks.
- //
- // The default value (boot time) is 1.
- //
- // Note: Currently, OMX components have default rank 0x100, while all
- // Codec2.0 software components have default rank 0x200.
- int option = ::android::base::GetIntProperty("debug.stagefright.ccodec", 1);
-
- // Obtain Codec2Client
- std::vector<Traits> traits = Codec2Client::ListComponents();
-
- MediaCodecsXmlParser parser;
- if (option == 0) {
- parser.parseXmlFilesInSearchDirs();
- } else {
- parser.parseXmlFilesInSearchDirs(
- { "media_codecs_c2.xml", "media_codecs_performance_c2.xml" });
- }
- if (parser.getParsingStatus() != OK) {
- ALOGD("XML parser no good");
- return OK;
- }
-
- bool surfaceTest(Codec2Client::CreateInputSurface());
- if (option == 0 || (option != 4 && !surfaceTest)) {
- buildOmxInfo(parser, writer);
- }
-
- for (const Traits& trait : traits) {
- C2Component::rank_t rank = trait.rank;
-
- std::shared_ptr<Codec2Client::Interface> intf =
- Codec2Client::CreateInterfaceByName(trait.name.c_str());
- if (!intf || parser.getCodecMap().count(intf->getName()) == 0) {
- ALOGD("%s not found in xml", trait.name.c_str());
- continue;
- }
- std::string canonName = intf->getName();
-
- // TODO: Remove this block once all codecs are enabled by default.
- switch (option) {
- case 0:
- continue;
- case 1:
- if (hasPrefix(canonName, "c2.vda.")) {
- break;
- }
- if (hasPrefix(canonName, "c2.android.")) {
- if (trait.domain == C2Component::DOMAIN_AUDIO) {
- rank = 1;
- break;
- }
- break;
- }
- if (hasSuffix(canonName, ".avc.decoder") ||
- hasSuffix(canonName, ".avc.encoder")) {
- rank = std::numeric_limits<decltype(rank)>::max();
- break;
- }
- continue;
- case 2:
- if (hasPrefix(canonName, "c2.vda.")) {
- break;
- }
- if (hasPrefix(canonName, "c2.android.")) {
- rank = 1;
- break;
- }
- if (hasSuffix(canonName, ".avc.decoder") ||
- hasSuffix(canonName, ".avc.encoder")) {
- rank = std::numeric_limits<decltype(rank)>::max();
- break;
- }
- continue;
- case 3:
- if (hasPrefix(canonName, "c2.android.")) {
- rank = 1;
- }
- break;
- }
-
- ALOGV("canonName = %s", canonName.c_str());
- std::unique_ptr<MediaCodecInfoWriter> codecInfo = writer->addMediaCodecInfo();
- codecInfo->setName(trait.name.c_str());
- codecInfo->setOwner(("codec2::" + trait.owner).c_str());
- const MediaCodecsXmlParser::CodecProperties &codec = parser.getCodecMap().at(canonName);
-
- bool encoder = trait.kind == C2Component::KIND_ENCODER;
- typename std::underlying_type<MediaCodecInfo::Attributes>::type attrs = 0;
-
- if (encoder) {
- attrs |= MediaCodecInfo::kFlagIsEncoder;
- }
- if (trait.owner == "software") {
- attrs |= MediaCodecInfo::kFlagIsSoftwareOnly;
- } else {
- attrs |= MediaCodecInfo::kFlagIsVendor;
- if (trait.owner == "vendor-software") {
- attrs |= MediaCodecInfo::kFlagIsSoftwareOnly;
- } else if (codec.quirkSet.find("attribute::software-codec") == codec.quirkSet.end()) {
- attrs |= MediaCodecInfo::kFlagIsHardwareAccelerated;
- }
- }
- codecInfo->setAttributes(attrs);
- codecInfo->setRank(rank);
-
- for (const std::string &alias : codec.aliases) {
- codecInfo->addAlias(alias.c_str());
- }
-
- for (auto typeIt = codec.typeMap.begin(); typeIt != codec.typeMap.end(); ++typeIt) {
- const std::string &mediaType = typeIt->first;
- const MediaCodecsXmlParser::AttributeMap &attrMap = typeIt->second;
- std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> caps =
- codecInfo->addMediaType(mediaType.c_str());
- for (auto attrIt = attrMap.begin(); attrIt != attrMap.end(); ++attrIt) {
- std::string key, value;
- std::tie(key, value) = *attrIt;
- if (key.find("feature-") == 0 && key.find("feature-bitrate-modes") != 0) {
- caps->addDetail(key.c_str(), std::stoi(value));
- } else {
- caps->addDetail(key.c_str(), value.c_str());
- }
- }
-
- bool gotProfileLevels = false;
- if (intf) {
- std::shared_ptr<C2Mapper::ProfileLevelMapper> mapper =
- C2Mapper::GetProfileLevelMapper(trait.mediaType);
- // if we don't know the media type, pass through all values unmapped
-
- // TODO: we cannot find levels that are local 'maxima' without knowing the coding
- // e.g. H.263 level 45 and level 30 could be two values for highest level as
- // they don't include one another. For now we use the last supported value.
- C2StreamProfileLevelInfo pl(encoder /* output */, 0u);
- std::vector<C2FieldSupportedValuesQuery> profileQuery = {
- C2FieldSupportedValuesQuery::Possible(C2ParamField(&pl, &pl.profile))
- };
-
- c2_status_t err = intf->querySupportedValues(profileQuery, C2_DONT_BLOCK);
- ALOGV("query supported profiles -> %s | %s",
- asString(err), asString(profileQuery[0].status));
- if (err == C2_OK && profileQuery[0].status == C2_OK) {
- if (profileQuery[0].values.type == C2FieldSupportedValues::VALUES) {
- std::vector<std::shared_ptr<C2ParamDescriptor>> supportedParams;
- bool hdrSupported = false;
- err = intf->querySupportedParams(&supportedParams);
- if (err == C2_OK) {
- for (const std::shared_ptr<C2ParamDescriptor> &desc : supportedParams) {
- if (desc->index().coreIndex() == C2StreamHdrStaticInfo::CORE_INDEX) {
- hdrSupported = true;
- break;
- }
- }
- }
- ALOGV("HDR %ssupported", hdrSupported ? "" : "not ");
- for (C2Value::Primitive profile : profileQuery[0].values.values) {
- pl.profile = (C2Config::profile_t)profile.ref<uint32_t>();
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- err = intf->config({&pl}, C2_DONT_BLOCK, &failures);
- ALOGV("set profile to %u -> %s", pl.profile, asString(err));
- std::vector<C2FieldSupportedValuesQuery> levelQuery = {
- C2FieldSupportedValuesQuery::Current(C2ParamField(&pl, &pl.level))
- };
- err = intf->querySupportedValues(levelQuery, C2_DONT_BLOCK);
- ALOGV("query supported levels -> %s | %s",
- asString(err), asString(levelQuery[0].status));
- if (err == C2_OK && levelQuery[0].status == C2_OK) {
- if (levelQuery[0].values.type == C2FieldSupportedValues::VALUES
- && levelQuery[0].values.values.size() > 0) {
- C2Value::Primitive level = levelQuery[0].values.values.back();
- pl.level = (C2Config::level_t)level.ref<uint32_t>();
- ALOGV("supporting level: %u", pl.level);
- bool added = false;
- int32_t sdkProfile, sdkLevel;
- if (mapper && mapper->mapProfile(pl.profile, &sdkProfile)
- && mapper->mapLevel(pl.level, &sdkLevel)) {
- caps->addProfileLevel(
- (uint32_t)sdkProfile, (uint32_t)sdkLevel);
- gotProfileLevels = true;
- added = true;
- } else if (!mapper) {
- sdkProfile = pl.profile;
- sdkLevel = pl.level;
- caps->addProfileLevel(pl.profile, pl.level);
- gotProfileLevels = true;
- added = true;
- }
- if (added && hdrSupported) {
- static ALookup<int32_t, int32_t> sHdrProfileMap = {
- { VP9Profile2, VP9Profile2HDR },
- { VP9Profile3, VP9Profile3HDR },
- };
- int32_t sdkHdrProfile;
- if (sHdrProfileMap.lookup(sdkProfile, &sdkHdrProfile)) {
- caps->addProfileLevel(
- (uint32_t)sdkHdrProfile, (uint32_t)sdkLevel);
- }
- }
-
- // for H.263 also advertise the second highest level if the
- // codec supports level 45, as level 45 only covers level 10
- // TODO: move this to some form of a setting so it does not
- // have to be here
- if (mediaType == MIMETYPE_VIDEO_H263) {
- C2Config::level_t nextLevel = C2Config::LEVEL_UNUSED;
- for (C2Value::Primitive v : levelQuery[0].values.values) {
- C2Config::level_t level =
- (C2Config::level_t)v.ref<uint32_t>();
- if (level < C2Config::LEVEL_H263_45
- && level > nextLevel) {
- nextLevel = level;
- }
- }
- if (nextLevel != C2Config::LEVEL_UNUSED
- && nextLevel != pl.level
- && mapper
- && mapper->mapProfile(pl.profile, &sdkProfile)
- && mapper->mapLevel(nextLevel, &sdkLevel)) {
- caps->addProfileLevel(
- (uint32_t)sdkProfile, (uint32_t)sdkLevel);
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (!gotProfileLevels) {
- if (mediaType == MIMETYPE_VIDEO_VP9) {
- if (encoder) {
- caps->addProfileLevel(VP9Profile0, VP9Level41);
- } else {
- caps->addProfileLevel(VP9Profile0, VP9Level5);
- caps->addProfileLevel(VP9Profile2, VP9Level5);
- caps->addProfileLevel(VP9Profile2HDR, VP9Level5);
- }
- } else if (mediaType == MIMETYPE_VIDEO_HEVC && !encoder) {
- caps->addProfileLevel(HEVCProfileMain, HEVCMainTierLevel51);
- caps->addProfileLevel(HEVCProfileMainStill, HEVCMainTierLevel51);
- } else if (mediaType == MIMETYPE_VIDEO_VP8) {
- if (encoder) {
- caps->addProfileLevel(VP8ProfileMain, VP8Level_Version0);
- } else {
- caps->addProfileLevel(VP8ProfileMain, VP8Level_Version0);
- }
- } else if (mediaType == MIMETYPE_VIDEO_AVC) {
- if (encoder) {
- caps->addProfileLevel(AVCProfileBaseline, AVCLevel41);
-// caps->addProfileLevel(AVCProfileConstrainedBaseline, AVCLevel41);
- caps->addProfileLevel(AVCProfileMain, AVCLevel41);
- } else {
- caps->addProfileLevel(AVCProfileBaseline, AVCLevel52);
- caps->addProfileLevel(AVCProfileConstrainedBaseline, AVCLevel52);
- caps->addProfileLevel(AVCProfileMain, AVCLevel52);
- caps->addProfileLevel(AVCProfileConstrainedHigh, AVCLevel52);
- caps->addProfileLevel(AVCProfileHigh, AVCLevel52);
- }
- } else if (mediaType == MIMETYPE_VIDEO_MPEG4) {
- if (encoder) {
- caps->addProfileLevel(MPEG4ProfileSimple, MPEG4Level2);
- } else {
- caps->addProfileLevel(MPEG4ProfileSimple, MPEG4Level3);
- }
- } else if (mediaType == MIMETYPE_VIDEO_H263) {
- if (encoder) {
- caps->addProfileLevel(H263ProfileBaseline, H263Level45);
- } else {
- caps->addProfileLevel(H263ProfileBaseline, H263Level30);
- caps->addProfileLevel(H263ProfileBaseline, H263Level45);
- caps->addProfileLevel(H263ProfileISWV2, H263Level30);
- caps->addProfileLevel(H263ProfileISWV2, H263Level45);
- }
- } else if (mediaType == MIMETYPE_VIDEO_MPEG2 && !encoder) {
- caps->addProfileLevel(MPEG2ProfileSimple, MPEG2LevelHL);
- caps->addProfileLevel(MPEG2ProfileMain, MPEG2LevelHL);
- }
- }
-
- // TODO: get this from intf() as well, but how do we map them to
- // MediaCodec color formats?
- if (mediaType.find("video") != std::string::npos) {
- // vendor video codecs prefer opaque format
- if (trait.name.find("android") == std::string::npos) {
- caps->addColorFormat(COLOR_FormatSurface);
- }
- caps->addColorFormat(COLOR_FormatYUV420Flexible);
- caps->addColorFormat(COLOR_FormatYUV420Planar);
- caps->addColorFormat(COLOR_FormatYUV420SemiPlanar);
- caps->addColorFormat(COLOR_FormatYUV420PackedPlanar);
- caps->addColorFormat(COLOR_FormatYUV420PackedSemiPlanar);
- // framework video encoders must support surface format, though it is unclear
- // that they will be able to map it if it is opaque
- if (encoder && trait.name.find("android") != std::string::npos) {
- caps->addColorFormat(COLOR_FormatSurface);
- }
- }
- }
- }
- return OK;
-}
-
-} // namespace android
-
-extern "C" android::MediaCodecListBuilderBase *CreateBuilder() {
- return new android::Codec2InfoBuilder;
-}
-
diff --git a/media/sfplugin/Codec2InfoBuilder.h b/media/sfplugin/Codec2InfoBuilder.h
deleted file mode 100644
index 30c189e..0000000
--- a/media/sfplugin/Codec2InfoBuilder.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef CODEC2_INFO_BUILDER_H_
-#define CODEC2_INFO_BUILDER_H_
-
-#include <media/stagefright/MediaCodecList.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class Codec2InfoBuilder : public MediaCodecListBuilderBase {
-public:
- Codec2InfoBuilder() = default;
- ~Codec2InfoBuilder() override = default;
- status_t buildMediaCodecList(MediaCodecListWriter* writer) override;
-};
-
-} // namespace android
-
-#endif // CODEC2_INFO_BUILDER_H_
diff --git a/media/sfplugin/InputSurfaceWrapper.h b/media/sfplugin/InputSurfaceWrapper.h
deleted file mode 100644
index d9c4eec..0000000
--- a/media/sfplugin/InputSurfaceWrapper.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef INPUT_SURFACE_WRAPPER_H_
-#define INPUT_SURFACE_WRAPPER_H_
-
-#include <codec2/hidl/client.h>
-#include <system/graphics.h>
-
-namespace android {
-
-/**
- * Wrapper interface around InputSurface.
- */
-class InputSurfaceWrapper {
-public:
- InputSurfaceWrapper()
- : mDataSpace(HAL_DATASPACE_UNKNOWN) {
- }
-
- virtual ~InputSurfaceWrapper() = default;
-
- /**
- * Connect the surface with |comp|. A surface can
- * connect to at most one component at a time.
- *
- * \return OK successfully connected to |comp|
- * \return ALREADY_EXISTS already connected to another component.
- */
- virtual status_t connect(
- const std::shared_ptr<Codec2Client::Component> &comp) = 0;
-
- /**
- * Disconnect the surface from the component if any.
- */
- virtual void disconnect() = 0;
-
- /**
- * Start pushing buffers to the surface.
- */
- virtual status_t start() = 0;
-
- /**
- * Ref: GraphicBufferSource::signalEndOfInputStream.
- */
- virtual status_t signalEndOfInputStream() = 0;
-
- /// Input Surface configuration
- struct Config {
- // IN PARAMS (GBS)
- float mMinFps; // minimum fps (repeat frame to achieve this)
- float mMaxFps; // max fps (via frame drop)
- float mCaptureFps; // capture fps
- float mCodedFps; // coded fps
- bool mSuspended; // suspended
- int64_t mTimeOffsetUs; // time offset (input => codec)
- int64_t mSuspendAtUs; // suspend/resume time
- int64_t mStartAtUs; // start time
- bool mStopped; // stopped
- int64_t mStopAtUs; // stop time
-
- // OUT PARAMS (GBS)
- int64_t mInputDelayUs; // delay between encoder input and surface input
-
- // IN PARAMS (CODEC WRAPPER)
- float mFixedAdjustedFps; // fixed fps via PTS manipulation
- float mMinAdjustedFps; // minimum fps via PTS manipulation
- };
-
- /**
- * Configures input surface.
- *
- * \param config configuration. This can be updated during this call to provide output
- * parameters, but not to provide configured parameters (to avoid continually
- * reconfiguring)
- */
- virtual status_t configure(Config &config) = 0;
-
- /**
- * Configures desired data space.
- *
- * \param dataSpace desired data space
- */
- inline void setDataSpace(android_dataspace dataSpace) {
- mDataSpace = dataSpace;
- }
-
-protected:
- android_dataspace mDataSpace;
-};
-
-} // namespace android
-
-#endif // INPUT_SURFACE_WRAPPER_H_
diff --git a/media/sfplugin/ReflectedParamUpdater.cpp b/media/sfplugin/ReflectedParamUpdater.cpp
deleted file mode 100644
index 880d4a5..0000000
--- a/media/sfplugin/ReflectedParamUpdater.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * Copyright (C) 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 "ReflectedParamUpdater"
-#include <utils/Log.h>
-
-#include <iostream>
-#include <set>
-#include <sstream>
-
-#include <C2Debug.h>
-#include <C2ParamInternal.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include "ReflectedParamUpdater.h"
-
-namespace android {
-
-std::string ReflectedParamUpdater::Dict::debugString(size_t indent_) const {
- std::string indent(indent_, ' ');
- std::stringstream s;
- s << "Dict {" << std::endl;
-
- for (const auto &it : *this) {
- s << indent << " ";
-
- C2Value c2Value;
- int32_t int32Value;
- uint32_t uint32Value;
- int64_t int64Value;
- uint64_t uint64Value;
- float floatValue;
- sp<ABuffer> bufValue;
- AString strValue;
- if (it.second.find(&c2Value)) {
- switch (c2Value.type()) {
- case C2Value::INT32:
- (void)c2Value.get(&int32Value);
- s << "c2::i32 " << it.first << " = " << int32Value;
- break;
- case C2Value::UINT32:
- (void)c2Value.get(&uint32Value);
- s << "c2::u32 " << it.first << " = " << uint32Value;
- break;
- case C2Value::CNTR32:
- // dump counter value as unsigned
- (void)c2Value.get((c2_cntr32_t*)&uint32Value);
- s << "c2::c32 " << it.first << " = " << uint32Value;
- break;
- case C2Value::INT64:
- (void)c2Value.get(&int64Value);
- s << "c2::i64 " << it.first << " = " << int64Value;
- break;
- case C2Value::UINT64:
- (void)c2Value.get(&uint64Value);
- s << "c2::u64 " << it.first << " = " << uint64Value;
- break;
- case C2Value::CNTR64:
- // dump counter value as unsigned
- (void)c2Value.get((c2_cntr64_t*)&uint64Value);
- s << "c2::c64 " << it.first << " = " << uint64Value;
- break;
- case C2Value::FLOAT:
- (void)c2Value.get(&floatValue);
- s << "c2::float " << it.first << " = " << floatValue;
- break;
- default:
- // dump unsupported values for debugging, these should not be used
- s << "c2::unsupported " << it.first;
- }
- } else if (it.second.find(&int32Value)) {
- s << "int32_t " << it.first << " = " << int32Value;
- } else if (it.second.find(&int64Value)) {
- s << "int64_t " << it.first << " = " << int64Value;
- } else if (it.second.find(&strValue)) {
- s << "string " << it.first << " = \"" << strValue.c_str() << "\"";
- } else if (it.second.find(&bufValue)) {
- s << "Buffer " << it.first << " = ";
- if (bufValue != nullptr && bufValue->data() != nullptr && bufValue->size() <= 64) {
- s << "{" << std::endl;
- AString tmp;
- hexdump(bufValue->data(), bufValue->size(), indent_ + 4, &tmp);
- s << tmp.c_str() << indent << " }";
- } else {
- s << (void*)bufValue.get();
- }
- } else {
- // dump unsupported values for debugging, this should never happen.
- s << "unsupported " << it.first;
- }
- s << std::endl;
- }
- s << indent << "}";
-
- return s.str();
-}
-
-void ReflectedParamUpdater::addParamDesc(
- const std::shared_ptr<C2ParamReflector> &reflector,
- const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs) {
- for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
- std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
- desc->index().coreIndex());
- if (structDesc == nullptr) {
- ALOGD("Could not describe %s", desc->name().c_str());
- continue;
- }
- addParamDesc(desc, *structDesc, reflector, true /* markVendor */);
- }
-
- // TEMP: also add vendor parameters as non-vendor
- for (const std::shared_ptr<C2ParamDescriptor> &desc : paramDescs) {
- if (!desc->index().isVendor()) {
- continue;
- }
- std::unique_ptr<C2StructDescriptor> structDesc = reflector->describe(
- desc->index().coreIndex());
- if (structDesc) {
- addParamDesc(desc, *structDesc, reflector, false /* markVendor */);
- }
- }
-}
-
-void ReflectedParamUpdater::addParamStructDesc(
- std::shared_ptr<C2ParamDescriptor> desc,
- C2String path,
- size_t offset,
- const C2StructDescriptor &structDesc,
- const std::shared_ptr<C2ParamReflector> &reflector) {
- for (auto it = structDesc.begin(); it != structDesc.end(); ++it) {
- C2String fieldName = path + "." + it->name();
- if (it->type() & C2FieldDescriptor::STRUCT_FLAG) {
- if (reflector == nullptr || it->extent() != 1) {
- ALOGD("ignored struct field %s", fieldName.c_str());
- continue;
- }
- std::unique_ptr<C2StructDescriptor> structDesc_ = reflector->describe(
- C2Param::CoreIndex(it->type()).coreIndex());
- if (structDesc_ == nullptr) {
- ALOGD("Could not describe structure of %s", fieldName.c_str());
- continue;
- }
- addParamStructDesc(desc, fieldName, offset + _C2ParamInspector::GetOffset(*it),
- *structDesc_, reflector);
- continue;
- }
-
- // verify extent and type
- switch (it->type()) {
- case C2FieldDescriptor::INT32:
- case C2FieldDescriptor::UINT32:
- case C2FieldDescriptor::CNTR32:
- case C2FieldDescriptor::INT64:
- case C2FieldDescriptor::UINT64:
- case C2FieldDescriptor::CNTR64:
- case C2FieldDescriptor::FLOAT:
- if (it->extent() != 1) {
- ALOGD("extent() != 1 for single value type: %s", fieldName.c_str());
- continue;
- }
- break;
- case C2FieldDescriptor::STRING:
- case C2FieldDescriptor::BLOB:
- break;
-
- default:
- ALOGD("Unrecognized type: %s", fieldName.c_str());
- continue;
- }
-
- ALOGV("%s registered", fieldName.c_str());
- // TODO: get the proper size by iterating through the fields.
- // only insert fields the very first time
- mMap.emplace(fieldName, FieldDesc {
- desc,
- std::make_unique<C2FieldDescriptor>(
- it->type(), it->extent(), it->name(),
- _C2ParamInspector::GetOffset(*it),
- _C2ParamInspector::GetSize(*it)),
- offset,
- });
- }
-}
-
-void ReflectedParamUpdater::addParamDesc(
- std::shared_ptr<C2ParamDescriptor> desc, const C2StructDescriptor &structDesc,
- const std::shared_ptr<C2ParamReflector> &reflector, bool markVendor) {
- C2String paramName = desc->name();
-
- // prefix vendor parameters
- if (desc->index().isVendor() && markVendor) {
- paramName = "vendor." + paramName;
- }
- mParamNames.emplace(desc->index(), paramName);
-
- // also allow setting whole parameters in a binary fashion via ByteBuffer
- // this is opt-in for now
- auto it = mWholeParams.find(paramName);
- if (it != mWholeParams.end() && it->second.coreIndex() == desc->index().coreIndex()) {
- mMap.emplace(paramName, FieldDesc{ desc, nullptr, 0 /* offset */ });
- // don't add fields of whole parameters.
- return;
- }
-
- addParamStructDesc(desc, paramName, 0 /* offset */, structDesc, reflector);
-}
-
-void ReflectedParamUpdater::supportWholeParam(std::string name, C2Param::CoreIndex index) {
- mWholeParams.emplace(name, index);
-}
-
-std::string ReflectedParamUpdater::getParamName(C2Param::Index index) const {
- auto it = mParamNames.find(index);
- if (it != mParamNames.end()) {
- return it->second;
- }
-
- std::stringstream ret;
- ret << "<unknown " << index << ">";
- return ret.str();
-}
-
-void ReflectedParamUpdater::getParamIndicesFromMessage(
- const Dict &params,
- std::vector<C2Param::Index> *vec /* nonnull */) const {
- CHECK(vec != nullptr);
- vec->clear();
- std::set<C2Param::Index> indices;
- parseMessageAndDoWork(
- params,
- [&indices](const std::string &, const FieldDesc &desc, const void *, size_t) {
- indices.insert(desc.paramDesc->index());
- });
- for (const C2Param::Index &index : indices) {
- vec->push_back(index);
- }
-}
-
-void ReflectedParamUpdater::getParamIndicesForKeys(
- const std::vector<std::string> &keys,
- std::vector<C2Param::Index> *vec /* nonnull */) const {
- CHECK(vec != nullptr);
- vec->clear();
- std::set<C2Param::Index> indices;
-
- std::set<std::string> keyMap(keys.begin(), keys.end());
-
- ALOGV("in getParamIndicesForKeys with %zu keys and map of %zu entries",
- keyMap.size(), mMap.size());
- for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
- const std::string &name = kv.first;
- const FieldDesc &desc = kv.second;
- ALOGV("count of %s is %zu", name.c_str(), keyMap.count(name));
- if (keyMap.count(name) > 0) {
- indices.insert(desc.paramDesc->index());
- }
- }
-
- for (const C2Param::Index &index : indices) {
- vec->push_back(index);
- }
-}
-
-void ReflectedParamUpdater::updateParamsFromMessage(
- const Dict &params,
- std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const {
- CHECK(vec != nullptr);
-
- std::map<C2Param::Index, std::unique_ptr<C2Param>*> paramsMap;
- for (std::unique_ptr<C2Param> &param : *vec) {
- if (param && *param) {
- paramsMap[param->index()] = &param;
- }
- }
-
- parseMessageAndDoWork(
- params,
- [&paramsMap](const std::string &name, const FieldDesc &desc, const void *ptr, size_t size) {
- std::unique_ptr<C2Param> *param = nullptr;
- auto paramIt = paramsMap.find(desc.paramDesc->index());
- if (paramIt == paramsMap.end()) {
- ALOGD("%s found, but param #%d isn't present to update",
- name.c_str(), (int32_t)desc.paramDesc->index());
- return;
- }
- param = paramIt->second;
-
- struct _C2Param : public C2Param {
- using C2Param::C2Param;
- _C2Param(uint32_t size, uint32_t index) : C2Param(size, index) { }
- };
-
- // we will handle whole param updates as part of a flexible param update using
- // a zero offset.
- size_t offset = 0;
- size_t minOffset = 0;
-
- // if this descriptor has a field, use the offset and size and ensure that offset
- // is not part of the header
- if (desc.fieldDesc) {
- minOffset = sizeof(C2Param);
- offset = sizeof(C2Param) + desc.offset
- + _C2ParamInspector::GetOffset(*desc.fieldDesc);
- }
-
- // reallocate or trim flexible param (or whole param) as necessary
- if (!desc.fieldDesc /* whole param */ || desc.fieldDesc->extent() == 0) {
- // reallocate param if more space is needed
- if (param->get()->size() < offset + size) {
- if (size > INT32_MAX - offset || offset < minOffset) {
- // size too long or offset too early - abandon
- return;
- }
- C2Param *newParam = (C2Param *)::operator new(offset + size);
- new (newParam) _C2Param(offset + size, param->get()->index());
- if (offset > sizeof(C2Param)) {
- memcpy(newParam + 1, param->get() + 1, offset - sizeof(C2Param));
- }
- param->reset(newParam);
- } else if (param->get()->size() > offset + size) {
- // trim parameter size
- _C2ParamInspector::TrimParam(param->get(), offset + size);
- }
- } else if (desc.fieldDesc->type() == C2FieldDescriptor::BLOB) {
- // zero fill blobs if updating with smaller blob
- if (desc.fieldDesc->extent() > size) {
- memset((uint8_t *)(param->get()) + offset + size, 0,
- desc.fieldDesc->extent() - size);
- }
- }
-
- memcpy((uint8_t *)(param->get()) + offset, ptr, size);
- });
-}
-
-void ReflectedParamUpdater::parseMessageAndDoWork(
- const Dict &params,
- std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const {
- for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
- const std::string &name = kv.first;
- const FieldDesc &desc = kv.second;
- auto param = params.find(name);
- if (param == params.end()) {
- continue;
- }
-
- // handle whole parameters
- if (!desc.fieldDesc) {
- sp<ABuffer> tmp;
- if (param->second.find(&tmp) && tmp != nullptr) {
- C2Param *tmpAsParam = C2Param::From(tmp->data(), tmp->size());
- if (tmpAsParam && tmpAsParam->type().type() == desc.paramDesc->index().type()) {
- work(name, desc, tmp->data(), tmp->size());
- } else {
- ALOGD("Param blob does not match param for '%s' (%p, %x vs %x)",
- name.c_str(), tmpAsParam, tmpAsParam ? tmpAsParam->type().type() : 0xDEADu,
- desc.paramDesc->index().type());
- }
- }
- continue;
- }
-
- int32_t int32Value;
- int64_t int64Value;
- C2Value c2Value;
-
- C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
- size_t fieldExtent = desc.fieldDesc->extent();
- switch (fieldType) {
- case C2FieldDescriptor::INT32:
- if ((param->second.find(&c2Value) && c2Value.get(&int32Value))
- || param->second.find(&int32Value)) {
- work(name, desc, &int32Value, sizeof(int32Value));
- }
- break;
- case C2FieldDescriptor::UINT32:
- if ((param->second.find(&c2Value) && c2Value.get((uint32_t*)&int32Value))
- || param->second.find(&int32Value)) {
- work(name, desc, &int32Value, sizeof(int32Value));
- }
- break;
- case C2FieldDescriptor::CNTR32:
- if ((param->second.find(&c2Value) && c2Value.get((c2_cntr32_t*)&int32Value))
- || param->second.find(&int32Value)) {
- work(name, desc, &int32Value, sizeof(int32Value));
- }
- break;
- case C2FieldDescriptor::INT64:
- if ((param->second.find(&c2Value) && c2Value.get(&int64Value))
- || param->second.find(&int64Value)) {
- work(name, desc, &int64Value, sizeof(int64Value));
- }
- break;
- case C2FieldDescriptor::UINT64:
- if ((param->second.find(&c2Value) && c2Value.get((uint64_t*)&int64Value))
- || param->second.find(&int64Value)) {
- work(name, desc, &int64Value, sizeof(int64Value));
- }
- break;
- case C2FieldDescriptor::CNTR64:
- if ((param->second.find(&c2Value) && c2Value.get((c2_cntr64_t*)&int64Value))
- || param->second.find(&int64Value)) {
- work(name, desc, &int64Value, sizeof(int64Value));
- }
- break;
- case C2FieldDescriptor::FLOAT: {
- float tmp;
- if (param->second.find(&c2Value) && c2Value.get(&tmp)) {
- work(name, desc, &tmp, sizeof(tmp));
- }
- break;
- }
- case C2FieldDescriptor::STRING: {
- AString tmp;
- if (!param->second.find(&tmp)) {
- break;
- }
- if (fieldExtent > 0 && tmp.size() >= fieldExtent) {
- AString truncated(tmp, 0, fieldExtent - 1);
- ALOGD("String value too long to fit: original \"%s\" truncated to \"%s\"",
- tmp.c_str(), truncated.c_str());
- tmp = truncated;
- }
- work(name, desc, tmp.c_str(), tmp.size() + 1);
- break;
- }
-
- case C2FieldDescriptor::BLOB: {
- sp<ABuffer> tmp;
- if (!param->second.find(&tmp) || tmp == nullptr) {
- break;
- }
-
- if (fieldExtent > 0 && tmp->size() > fieldExtent) {
- ALOGD("Blob value too long to fit. Truncating.");
- tmp->setRange(tmp->offset(), fieldExtent);
- }
- work(name, desc, tmp->data(), tmp->size());
- break;
- }
-
- default:
- ALOGD("Unsupported data type for %s", name.c_str());
- break;
- }
- }
-}
-
-ReflectedParamUpdater::Dict
-ReflectedParamUpdater::getParams(const std::vector<std::unique_ptr<C2Param>> &params_) const {
- std::vector<C2Param*> params;
- params.resize(params_.size());
- std::transform(params_.begin(), params_.end(), params.begin(),
- [](const std::unique_ptr<C2Param>& p) -> C2Param* { return p.get(); });
- return getParams(params);
-}
-
-ReflectedParamUpdater::Dict
-ReflectedParamUpdater::getParams(const std::vector<C2Param*> &params) const {
- Dict ret;
-
- // convert vector to map
- std::map<C2Param::Index, C2Param *> paramsMap;
- for (C2Param *param : params) {
- if (param != nullptr && *param) {
- paramsMap[param->index()] = param;
- }
- }
-
- for (const std::pair<const std::string, FieldDesc> &kv : mMap) {
- const std::string &name = kv.first;
- const FieldDesc &desc = kv.second;
- if (paramsMap.count(desc.paramDesc->index()) == 0) {
- continue;
- }
- C2Param *param = paramsMap[desc.paramDesc->index()];
- Value value;
-
- // handle whole params first
- if (!desc.fieldDesc) {
- sp<ABuffer> buf = ABuffer::CreateAsCopy(param, param->size());
- value.set(buf);
- ret.emplace(name, value);
- continue;
- }
-
- size_t offset = sizeof(C2Param) + desc.offset
- + _C2ParamInspector::GetOffset(*desc.fieldDesc);
- uint8_t *data = (uint8_t *)param + offset;
- C2FieldDescriptor::type_t fieldType = desc.fieldDesc->type();
- switch (fieldType) {
- case C2FieldDescriptor::STRING: {
- size_t length = desc.fieldDesc->extent();
- if (length == 0) {
- length = param->size() - offset;
- }
-
- if (param->size() < length || param->size() - length < offset) {
- ALOGD("param too small for string: length %zu size %zu offset %zu",
- length, param->size(), offset);
- break;
- }
- value.set(AString((char *)data, strnlen((char *)data, length)));
- break;
- }
-
- case C2FieldDescriptor::BLOB: {
- size_t length = desc.fieldDesc->extent();
- if (length == 0) {
- length = param->size() - offset;
- }
-
- if (param->size() < length || param->size() - length < offset) {
- ALOGD("param too small for blob: length %zu size %zu offset %zu",
- length, param->size(), offset);
- break;
- }
-
- sp<ABuffer> buf = ABuffer::CreateAsCopy(data, length);
- value.set(buf);
- break;
- }
-
- default: {
- size_t valueSize = C2Value::SizeFor((C2Value::type_t)fieldType);
- if (param->size() < valueSize || param->size() - valueSize < offset) {
- ALOGD("param too small for c2value: size %zu offset %zu",
- param->size(), offset);
- break;
- }
-
- C2Value c2Value;
- switch (fieldType) {
- case C2FieldDescriptor::INT32: c2Value = *((int32_t *)data); break;
- case C2FieldDescriptor::UINT32: c2Value = *((uint32_t *)data); break;
- case C2FieldDescriptor::CNTR32: c2Value = *((c2_cntr32_t *)data); break;
- case C2FieldDescriptor::INT64: c2Value = *((int64_t *)data); break;
- case C2FieldDescriptor::UINT64: c2Value = *((uint64_t *)data); break;
- case C2FieldDescriptor::CNTR64: c2Value = *((c2_cntr64_t *)data); break;
- case C2FieldDescriptor::FLOAT: c2Value = *((float *)data); break;
- default:
- ALOGD("Unsupported data type for %s", name.c_str());
- continue;
- }
- value.set(c2Value);
- }
- }
- ret.emplace(name, value);
- }
- return ret;
-}
-
-void ReflectedParamUpdater::clear() {
- mMap.clear();
-}
-
-} // namespace android
diff --git a/media/sfplugin/ReflectedParamUpdater.h b/media/sfplugin/ReflectedParamUpdater.h
deleted file mode 100644
index 5436ba5..0000000
--- a/media/sfplugin/ReflectedParamUpdater.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef REFLECTED_PARAM_BUILDER_H_
-#define REFLECTED_PARAM_BUILDER_H_
-
-#include <map>
-#include <memory>
-
-#include <C2.h>
-#include <C2Param.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AData.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AString.h>
-
-namespace android {
-
-/**
- * Utility class to query and update Codec 2.0 configuration values. Use custom dictionary as
- * AMessage cannot represent all types of Codec 2.0 parameters and C2Value cannot represent
- * all types of SDK values. We want to be precise when setting standard parameters (use C2Value
- * for arithmetic values), but also support int32 and int64 for SDK values specifically for
- * vendor parameters (as SDK API does not allow specifying proper type.) When querying fields,
- * we can use C2Values as they are defined.
- *
- * Item => Codec 2.0 value mappings:
- * CValue::type => type
- * int32 => int32, ctr32 or uint32
- * int64 => int64, ctr64 or uint64
- * AString => string
- * ABuffer => blob
- * 'Rect' => C2RectStruct (not exposed in SDK as a rectangle)
- */
-class ReflectedParamUpdater {
-public:
- ReflectedParamUpdater() = default;
- ~ReflectedParamUpdater() = default;
-
- /**
- * Element for values
- */
- struct Value : public AData<C2Value, int32_t, int64_t, AString, sp<ABuffer>>::Basic {
- // allow construction from base types
- Value() = default;
- explicit Value(C2Value i) { set(i); }
- explicit Value(int32_t i) { set(i); }
- explicit Value(int64_t i) { set(i); }
- explicit Value(const AString &i) { set(i); }
- explicit Value(const sp<ABuffer> &i) { set(i); }
- };
-
- struct Dict : public std::map<std::string, Value> {
- Dict() = default;
- std::string debugString(size_t indent = 0) const;
- };
-
- /**
- * Enumerates all fields of the parameter descriptors supplied, so that this opbject can later
- * query and update these.
- *
- * For now only first-level fields are supported. Also, array fields are not supported.
- *
- * \param reflector C2ParamReflector object for C2Param reflection.
- * \param paramDescs vector of C2ParamDescriptor objects that this object
- * would recognize when building params.
- */
- void addParamDesc(
- const std::shared_ptr<C2ParamReflector> &reflector,
- const std::vector<std::shared_ptr<C2ParamDescriptor>> &paramDescs);
-
- /**
- * Adds fields of a standard parameter (that may not be supported by the parameter reflector
- * or may not be listed as a supported value by the component). If the parameter name is
- * used for another parameter, this operation is a no-op. (Technically, this is by fields).
- *
- * \param T standard parameter type
- * \param name parameter name
- */
- template<typename T>
- void addStandardParam(const std::string &name, C2ParamDescriptor::attrib_t attrib =
- C2ParamDescriptor::IS_READ_ONLY) {
- addParamDesc(std::make_shared<C2ParamDescriptor>(
- C2Param::Index(T::PARAM_TYPE), attrib, name.c_str()),
- C2StructDescriptor((T*)nullptr), nullptr /* descriptor */);
- }
-
- /**
- * Adds fields of a structure (or a parameater) described by the struct descriptor. If
- * reflector is provided, fields of sub-structures are also added. Otherwise, only top-level
- * fundamental typed fields (arithmetic, string and blob) are added.
- *
- * \param paramDesc parameter descriptor
- * \param fieldDesc field descriptor
- * \param path path/name of the structure (field or parent parameter)
- * \param offset offset of the structure in the parameter
- * \param reflector C2ParamReflector object for C2Param reflection (may be null)
- */
- void addParamStructDesc(
- std::shared_ptr<C2ParamDescriptor> paramDesc, C2String path, size_t offset,
- const C2StructDescriptor &structDesc,
- const std::shared_ptr<C2ParamReflector> &reflector);
-
- /**
- * Adds fields of a parameter described by the struct descriptor. If reflector is provided,
- * fields of sub-structures are also added. Otherwise, only top-level fundamental typed fields
- * (arithmetic, string and blob) are added.
- *
- * \param paramDesc parameter descriptor
- * \param fieldDesc field descriptor
- * \param reflector C2ParamReflector object for C2Param reflection (may be null)
- * \param markVendor TEMP if true, prefix vendor parameter names with "vendor."
- */
- void addParamDesc(
- std::shared_ptr<C2ParamDescriptor> paramDesc, const C2StructDescriptor &structDesc,
- const std::shared_ptr<C2ParamReflector> &reflector,
- bool markVendor = true);
-
- /**
- * Add support for setting a parameter as a binary blob.
- *
- * \param name name of the parameter
- * \param coreIndex parameter (core) index
- */
- void supportWholeParam(std::string name, C2Param::CoreIndex coreIndex);
-
- /**
- * Returns the name of the parameter for an index.
- */
- std::string getParamName(C2Param::Index index) const;
-
- /**
- * Get list of param indices from field names and values in AMessage object.
- *
- * TODO: This should be in the order that they are listed by the component.
- *
- * \param params[in] Dict object with field name to value pairs.
- * \param vec[out] vector to store the indices from |params|.
- */
- void getParamIndicesFromMessage(
- const Dict &params,
- std::vector<C2Param::Index> *vec /* nonnull */) const;
-
- /**
- * Get list of param indices from field names (only) in AMessage object.
- *
- * \param params[in] Vector object with field names.
- * \param vec[out] vector to store the indices from |params|.
- */
- void getParamIndicesForKeys(
- const std::vector<std::string> &keys,
- std::vector<C2Param::Index> *vec /* nonnull */) const;
-
- /**
- * Update C2Param objects from field name and value in AMessage object.
- *
- * \param params[in] Dict object with field name to value pairs.
- * \param vec[in,out] vector of the C2Param objects to be updated.
- */
- void updateParamsFromMessage(
- const Dict &params,
- std::vector<std::unique_ptr<C2Param>> *vec /* nonnull */) const;
-
- /**
- * Get fields from C2Param objects in AMessage object.
- *
- * \param params[in] vector of the C2Param objects to be queried
- * \return a Dict object containing the known parameters
- */
- Dict getParams(
- const std::vector<C2Param*> &params /* nonnull */) const;
-
- Dict getParams(
- const std::vector<std::unique_ptr<C2Param>> &params /* nonnull */) const;
-
- /**
- * Clear param descriptors in this object.
- */
- void clear();
-
-private:
- struct FieldDesc {
- std::shared_ptr<C2ParamDescriptor> paramDesc;
- std::unique_ptr<C2FieldDescriptor> fieldDesc;
- size_t offset;
- };
- std::map<std::string, FieldDesc> mMap;
- std::map<C2Param::Index, std::string> mParamNames;
- std::map<std::string, C2Param::CoreIndex> mWholeParams;
-
- void parseMessageAndDoWork(
- const Dict &params,
- std::function<void(const std::string &, const FieldDesc &, const void *, size_t)> work) const;
-
- C2_DO_NOT_COPY(ReflectedParamUpdater);
-};
-
-} // namespace android
-
-#endif // REFLECTED_PARAM_BUILDER_H_
diff --git a/media/sfplugin/SkipCutBuffer.cpp b/media/sfplugin/SkipCutBuffer.cpp
deleted file mode 100644
index 5762440..0000000
--- a/media/sfplugin/SkipCutBuffer.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2012 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 "SkipCutBuffer"
-#include <utils/Log.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/SkipCutBuffer.h>
-
-namespace android {
-
-SkipCutBuffer::SkipCutBuffer(size_t skip, size_t cut, size_t num16BitChannels) {
-
- mWriteHead = 0;
- mReadHead = 0;
- mCapacity = 0;
- mCutBuffer = nullptr;
-
- if (num16BitChannels == 0 || num16BitChannels > INT32_MAX / 2) {
- ALOGW("# channels out of range: %zu, using passthrough instead", num16BitChannels);
- return;
- }
- size_t frameSize = num16BitChannels * 2;
- if (skip > INT32_MAX / frameSize || cut > INT32_MAX / frameSize
- || cut * frameSize > INT32_MAX - 4096) {
- ALOGW("out of range skip/cut: %zu/%zu, using passthrough instead",
- skip, cut);
- return;
- }
- skip *= frameSize;
- cut *= frameSize;
-
- mFrontPadding = mSkip = skip;
- mBackPadding = cut;
- mCapacity = cut + 4096;
- mCutBuffer = new (std::nothrow) char[mCapacity];
- ALOGV("skipcutbuffer %zu %zu %d", skip, cut, mCapacity);
-}
-
-SkipCutBuffer::~SkipCutBuffer() {
- delete[] mCutBuffer;
-}
-
-void SkipCutBuffer::submit(MediaBuffer *buffer) {
- if (mCutBuffer == nullptr) {
- // passthrough mode
- return;
- }
-
- int32_t offset = buffer->range_offset();
- int32_t buflen = buffer->range_length();
-
- // drop the initial data from the buffer if needed
- if (mFrontPadding > 0) {
- // still data left to drop
- int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
- offset += to_drop;
- buflen -= to_drop;
- buffer->set_range(offset, buflen);
- mFrontPadding -= to_drop;
- }
-
-
- // append data to cutbuffer
- char *src = ((char*) buffer->data()) + offset;
- write(src, buflen);
-
-
- // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
- // at least mBackPadding bytes in the cutbuffer
- char *dst = (char*) buffer->data();
- size_t copied = read(dst, buffer->size());
- buffer->set_range(0, copied);
-}
-
-template <typename T>
-void SkipCutBuffer::submitInternal(const sp<T>& buffer) {
- if (mCutBuffer == nullptr) {
- // passthrough mode
- return;
- }
-
- int32_t offset = buffer->offset();
- int32_t buflen = buffer->size();
-
- // drop the initial data from the buffer if needed
- if (mFrontPadding > 0) {
- // still data left to drop
- int32_t to_drop = (buflen < mFrontPadding) ? buflen : mFrontPadding;
- offset += to_drop;
- buflen -= to_drop;
- buffer->setRange(offset, buflen);
- mFrontPadding -= to_drop;
- }
-
-
- // append data to cutbuffer
- char *src = (char*) buffer->data();
- write(src, buflen);
-
-
- // the mediabuffer is now empty. Fill it from cutbuffer, always leaving
- // at least mBackPadding bytes in the cutbuffer
- char *dst = (char*) buffer->base();
- size_t copied = read(dst, buffer->capacity());
- buffer->setRange(0, copied);
-}
-
-void SkipCutBuffer::submit(const sp<ABuffer>& buffer) {
- submitInternal(buffer);
-}
-
-void SkipCutBuffer::submit(const sp<MediaCodecBuffer>& buffer) {
- submitInternal(buffer);
-}
-
-void SkipCutBuffer::clear() {
- mWriteHead = mReadHead = 0;
- mFrontPadding = mSkip;
-}
-
-void SkipCutBuffer::write(const char *src, size_t num) {
- int32_t sizeused = (mWriteHead - mReadHead);
- if (sizeused < 0) sizeused += mCapacity;
-
- // Everything must fit. Make sure the buffer is a little larger than needed,
- // so there is no ambiguity as to whether mWriteHead == mReadHead means buffer
- // full or empty
- size_t available = mCapacity - sizeused - 32;
- if (available < num) {
- int32_t newcapacity = mCapacity + (num - available);
- char * newbuffer = new char[newcapacity];
- memcpy(newbuffer, mCutBuffer, mCapacity);
- delete [] mCutBuffer;
- mCapacity = newcapacity;
- mCutBuffer = newbuffer;
- ALOGV("reallocated buffer at size %d", newcapacity);
- }
-
- size_t copyfirst = (mCapacity - mWriteHead);
- if (copyfirst > num) copyfirst = num;
- if (copyfirst) {
- memcpy(mCutBuffer + mWriteHead, src, copyfirst);
- num -= copyfirst;
- src += copyfirst;
- mWriteHead += copyfirst;
- CHECK_LE(mWriteHead, mCapacity);
- if (mWriteHead == mCapacity) mWriteHead = 0;
- if (num) {
- memcpy(mCutBuffer, src, num);
- mWriteHead += num;
- }
- }
-}
-
-size_t SkipCutBuffer::read(char *dst, size_t num) {
- int32_t available = (mWriteHead - mReadHead);
- if (available < 0) available += mCapacity;
-
- available -= mBackPadding;
- if (available <=0) {
- return 0;
- }
- if (available < int32_t(num)) {
- num = available;
- }
-
- size_t copyfirst = (mCapacity - mReadHead);
- if (copyfirst > num) copyfirst = num;
- if (copyfirst) {
- memcpy(dst, mCutBuffer + mReadHead, copyfirst);
- num -= copyfirst;
- dst += copyfirst;
- mReadHead += copyfirst;
- CHECK_LE(mReadHead, mCapacity);
- if (mReadHead == mCapacity) mReadHead = 0;
- if (num) {
- memcpy(dst, mCutBuffer, num);
- mReadHead += num;
- }
- }
- return available;
-}
-
-size_t SkipCutBuffer::size() {
- int32_t available = (mWriteHead - mReadHead);
- if (available < 0) available += mCapacity;
- return available;
-}
-
-} // namespace android
diff --git a/media/sfplugin/SkipCutBuffer.h b/media/sfplugin/SkipCutBuffer.h
deleted file mode 100644
index 0fb5690..0000000
--- a/media/sfplugin/SkipCutBuffer.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef SKIP_CUT_BUFFER_H_
-
-#define SKIP_CUT_BUFFER_H_
-
-#include <media/MediaCodecBuffer.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/foundation/ABuffer.h>
-
-namespace android {
-
-/**
- * utility class to cut the start and end off a stream of data in MediaBuffers
- *
- */
-class SkipCutBuffer: public RefBase {
- public:
- // 'skip' is the number of frames to skip from the beginning
- // 'cut' is the number of frames to cut from the end
- // 'num16BitChannels' is the number of channels, which are assumed to be 16 bit wide each
- SkipCutBuffer(size_t skip, size_t cut, size_t num16Channels);
-
- // Submit one MediaBuffer for skipping and cutting. This may consume all or
- // some of the data in the buffer, or it may add data to it.
- // After this, the caller should continue processing the buffer as usual.
- void submit(MediaBuffer *buffer);
- void submit(const sp<ABuffer>& buffer); // same as above, but with an ABuffer
- void submit(const sp<MediaCodecBuffer>& buffer); // same as above, but with an ABuffer
- void clear();
- size_t size(); // how many bytes are currently stored in the buffer
-
- protected:
- virtual ~SkipCutBuffer();
-
- private:
- void write(const char *src, size_t num);
- size_t read(char *dst, size_t num);
- template <typename T>
- void submitInternal(const sp<T>& buffer);
- int32_t mSkip;
- int32_t mFrontPadding;
- int32_t mBackPadding;
- int32_t mWriteHead;
- int32_t mReadHead;
- int32_t mCapacity;
- char* mCutBuffer;
- DISALLOW_EVIL_CONSTRUCTORS(SkipCutBuffer);
-};
-
-} // namespace android
-
-#endif // OMX_CODEC_H_
diff --git a/media/sfplugin/tests/Android.bp b/media/sfplugin/tests/Android.bp
deleted file mode 100644
index 8a6992f..0000000
--- a/media/sfplugin/tests/Android.bp
+++ /dev/null
@@ -1,56 +0,0 @@
-cc_test {
- name: "ccodec_test",
-
- srcs: [
- "ReflectedParamUpdater_test.cpp",
- ],
-
- include_dirs: [
- "hardware/google/av/media/sfplugin",
- ],
-
- shared_libs: [
- "libstagefright_ccodec",
- "libstagefright_codec2",
- "libstagefright_foundation",
- "libutils",
- ],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-}
-
-cc_test {
- name: "mc_sanity",
-
- srcs: [
- "MediaCodec_sanity_test.cpp",
- ],
-
- include_dirs: [
- "hardware/google/av/media/sfplugin",
- ],
-
- header_libs: [
- "libmediadrm_headers",
- ],
-
- shared_libs: [
- "libbinder",
- "libgui",
- "libmedia",
- "libmedia_omx",
- "libstagefright",
- "libstagefright_ccodec",
- "libstagefright_codec2",
- "libstagefright_foundation",
- "libutils",
- ],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-}
diff --git a/media/sfplugin/tests/MediaCodec_sanity_test.cpp b/media/sfplugin/tests/MediaCodec_sanity_test.cpp
deleted file mode 100644
index 3c43f1f..0000000
--- a/media/sfplugin/tests/MediaCodec_sanity_test.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * 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.
- */
-
-#include <stdlib.h>
-
-#include <algorithm>
-
-#include <binder/ProcessState.h>
-#include <gtest/gtest.h>
-#include <gui/Surface.h>
-#include <media/MediaCodecBuffer.h>
-#include <media/hardware/VideoAPI.h>
-#include <media/stagefright/MediaCodec.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <mediadrm/ICrypto.h>
-
-namespace android {
-
-class MediaCodecSanityTest : public ::testing::Test {
-public:
- MediaCodecSanityTest()
- : looper(new ALooper),
- cfg(new AMessage),
- ifmt(new AMessage),
- ofmt(new AMessage) {
- ProcessState::self()->startThreadPool();
- looper->start();
- }
-
- ~MediaCodecSanityTest() {
- if (codec != nullptr) {
- codec->release();
- }
- looper->stop();
- }
-
- sp<ALooper> looper;
- sp<MediaCodec> codec;
- sp<AMessage> cfg;
- sp<AMessage> ifmt;
- sp<AMessage> ofmt;
-};
-
-const static size_t kLinearBufferSize = 1048576;
-
-// data for a codec input frame
-struct FrameData {
- const uint8_t *data;
- size_t size;
- template<size_t N>
- constexpr FrameData(const uint8_t(&data_)[N]) : data(data_), size(N) { }
-};
-
-// one yellow frame of 240x180 (albeit 4:4:4)
-const uint8_t avcStream_A1[] = { // IDR frame
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0d, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
- 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x03, 0x20, 0xf1, 0x42, 0x99, 0x60,
-
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
-
- 0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x2b, 0xff, 0xfe, 0xd8, 0xe7, 0xf3, 0x2c, 0xa5, 0x60,
- 0xca, 0xbb, 0xf1, 0x5c, 0x44, 0x7c, 0x9a, 0xa5, 0xc3, 0xab, 0x2f, 0x77, 0x0a, 0x94, 0x0d, 0x19,
- 0x43, 0x3b, 0x4f, 0x25, 0xea, 0x66, 0x00, 0x01, 0x24, 0xcd, 0x35, 0x5f, 0xc2, 0x34, 0x89, 0xd1,
- 0xa5, 0x60, 0x09, 0x98, 0x00, 0x01, 0x1b, 0x0e, 0xcb, 0x0d, 0x04, 0x86, 0x94, 0xe2, 0x32, 0x3c,
- 0xdd, 0x0f,
-};
-
-FrameData avcStream_A[] __unused = { avcStream_A1 };
-
-// AVC stream of 2 yellow frames (240x180)
-const uint8_t avcStream_B1[] = { // IDR frame
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x64, 0x00, 0x0c, 0xac, 0xd9, 0x41, 0x41, 0xfa, 0x10, 0x00, 0x00,
- 0x03, 0x00, 0x10, 0x00, 0x00, 0x03, 0x02, 0x80, 0xf1, 0x42, 0x99, 0x60,
-
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
-
- 0x00, 0x00, 0x01, 0x65, 0x88, 0x84, 0x00, 0x33, 0xff, 0xfe, 0xdf, 0x32, 0xf8, 0x14, 0xd6, 0x25,
- 0xd0, 0x74, 0x42, 0x50, 0x84, 0x6f, 0xf4, 0xc2, 0x5c, 0x76, 0x37, 0x17, 0x72, 0xac, 0x52, 0xfc,
- 0xd6, 0x1f, 0xd2, 0xd0, 0x60, 0xb2, 0x20, 0x00, 0x10, 0x3d, 0x2a, 0xc0, 0xe4, 0x27, 0xcb, 0xce,
- 0xea, 0x25, 0x00, 0x81, 0x00, 0x00, 0x0f, 0x40, 0xbc, 0x81, 0x15, 0xc1, 0x65, 0x20, 0x80, 0x81,
- 0x7a, 0x57, 0x51,
-};
-
-const uint8_t avcStream_B2[] = { // P frame
- 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0xbf, 0xfe, 0x38, 0x40, 0x00, 0x0d, 0x48,
-};
-
-FrameData avcStream_B[] = { avcStream_B1, avcStream_B2 };
-
-class MediaCodecInputBufferSizeTest : public MediaCodecSanityTest,
- public ::testing::WithParamInterface<int32_t> {
-};
-
-TEST_P(MediaCodecInputBufferSizeTest, TestAvcDecoder) {
- codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
- cfg->setInt32("width", 320);
- cfg->setInt32("height", 240);
- cfg->setString("mime", MIMETYPE_VIDEO_AVC);
-
- const int32_t InputSize = GetParam();
- if (InputSize >= 0) {
- cfg->setInt32("max-input-size", InputSize);
- }
-
- EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
- EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
- int32_t maxInputSize;
- ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
- if (InputSize > 0) {
- EXPECT_EQ(maxInputSize, InputSize);
- } else {
- EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
- }
- EXPECT_EQ(codec->start(), OK);
- size_t ix;
- EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
- sp<MediaCodecBuffer> buf;
- EXPECT_EQ(codec->getInputBuffer(ix, &buf), OK);
- EXPECT_GE(buf->size(), (size_t)maxInputSize);
- EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
-}
-
-TEST_P(MediaCodecInputBufferSizeTest, TestVideoDecoder) {
- codec = MediaCodec::CreateByComponentName(looper, "c2.android.vp8.decoder");
- cfg->setInt32("width", 320);
- cfg->setInt32("height", 240);
- cfg->setString("mime", MIMETYPE_VIDEO_VP8);
-
- const int32_t InputSize = GetParam();
- if (InputSize >= 0) {
- cfg->setInt32("max-input-size", InputSize);
- }
-
- EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
- EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
- int32_t maxInputSize;
- ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
- if (InputSize > 0) {
- EXPECT_EQ(maxInputSize, InputSize);
- } else {
- EXPECT_GE(maxInputSize, 1 << 20); // 1 MB
- }
- EXPECT_EQ(codec->start(), OK);
- size_t ix;
- EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
- sp<MediaCodecBuffer> buf;
- EXPECT_EQ(codec->getInputBuffer(ix, &buf), OK);
- EXPECT_GE(buf->size(), (size_t)maxInputSize);
- EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
-}
-
-TEST_P(MediaCodecInputBufferSizeTest, TestAudioDecoder) {
- codec = MediaCodec::CreateByComponentName(looper, "c2.android.aac.decoder");
- cfg->setInt32("sample-rate", 44100);
- cfg->setInt32("channel-count", 2);
- cfg->setString("mime", MIMETYPE_AUDIO_AAC);
-
- const int32_t InputSize = GetParam();
- if (InputSize >= 0) {
- cfg->setInt32("max-input-size", InputSize);
- }
-
- EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
- EXPECT_EQ(codec->getInputFormat(&ifmt), OK);
- int32_t maxInputSize;
- if (InputSize > 0) {
- ASSERT_TRUE(ifmt->findInt32("max-input-size", &maxInputSize));
- EXPECT_EQ(maxInputSize, InputSize);
- } else {
- if (ifmt->findInt32("max-input-size", &maxInputSize)) {
- EXPECT_EQ(maxInputSize, 1 << 19); // 512 KB
- }
- maxInputSize = kLinearBufferSize; // input size is set by channel
- }
-
- EXPECT_EQ(codec->start(), OK);
- size_t ix;
- EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
- sp<MediaCodecBuffer> buf;
- EXPECT_EQ(codec->getInputBuffer(ix, &buf), OK);
- EXPECT_GE(buf->size(), (size_t)maxInputSize);
- EXPECT_LE(buf->size(), (size_t)maxInputSize + 4096u);
-}
-
-INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecInputBufferSizeTest, ::testing::Values(-1, 1234, 12345678));
-
-TEST_F(MediaCodecSanityTest, TestAvcDecoderHdrStaticInfo) {
- codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
- cfg->setInt32("width", 320);
- cfg->setInt32("height", 240);
- cfg->setString("mime", MIMETYPE_VIDEO_AVC);
- HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
- .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500, .y = 39850 },
- .mB = { .x = 6550, .y = 2300 }, .mW = { .x = 15635, .y = 16450 },
- .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
- .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
- };
- cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
-
- EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
- EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
- sp<ABuffer> oinfo;
- ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
- ASSERT_EQ(oinfo->size(), sizeof(info));
- EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)), 0);
-
- EXPECT_EQ(codec->start(), OK);
- // assume we can submit all input before dequeuing output
- size_t frameIx = 0;
- size_t ix;
- sp<MediaCodecBuffer> buf;
- for (const FrameData &frame : avcStream_B) {
- EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
- EXPECT_EQ(codec->getInputBuffer(ix, &buf), OK);
- ASSERT_GE(buf->capacity(), frame.size);
- memcpy(buf->base(), frame.data, frame.size);
- EXPECT_EQ(buf->setRange(0, frame.size), OK);
- bool eos = ++frameIx == NELEM(avcStream_B);
- EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
- eos ? BUFFER_FLAG_END_OF_STREAM : 0), OK);
- }
-
- size_t offset, size;
- int64_t ts;
- uint32_t flags;
- bool mInfoFormatChangedOk = true;
- bool mInfoBuffersChangedOk = true;
- while (true) {
- status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
- if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
- mInfoFormatChangedOk = false;
- } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
- mInfoBuffersChangedOk = false;
- } else {
- ASSERT_EQ(err, OK);
- break;
- }
- }
- EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
- EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
- ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
- ASSERT_EQ(oinfo->size(), sizeof(info));
- EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)), 0);
-}
-
-TEST_F(MediaCodecSanityTest, TestVideoDecoderHdrStaticInfo) {
- codec = MediaCodec::CreateByComponentName(looper, "c2.android.mpeg4.decoder");
- cfg->setInt32("width", 320);
- cfg->setInt32("height", 240);
- cfg->setString("mime", MIMETYPE_VIDEO_MPEG4);
- HDRStaticInfo info = { .mID = HDRStaticInfo::kType1, .sType1 = {
- .mR = { .x = 35400, .y = 14600 }, .mG = { .x = 8500, .y = 39850 },
- .mB = { .x = 6550, .y = 2300 }, .mW = { .x = 15635, .y = 16450 },
- .mMaxDisplayLuminance = 1000, .mMinDisplayLuminance = 1000,
- .mMaxContentLightLevel = 1000, .mMaxFrameAverageLightLevel = 120 }
- };
- cfg->setBuffer("hdr-static-info", ABuffer::CreateAsCopy(&info, sizeof(info)));
-
- EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
- EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
- sp<ABuffer> oinfo;
- ASSERT_TRUE(ofmt->findBuffer("hdr-static-info", &oinfo));
- ASSERT_EQ(oinfo->size(), sizeof(info));
- EXPECT_EQ(memcmp(oinfo->data(), &info, sizeof(info)), 0);
-}
-
-class MediaCodecByteBufferTest : public MediaCodecSanityTest,
- public ::testing::WithParamInterface<int32_t> {
-};
-
-TEST_P(MediaCodecByteBufferTest, TestVideoDecoder420Planar) {
- codec = MediaCodec::CreateByComponentName(looper, "c2.android.avc.decoder");
-// codec = MediaCodec::CreateByComponentName(looper, "OMX.google.h264.decoder");
- cfg->setInt32("width", 320);
- cfg->setInt32("height", 240);
- cfg->setString("mime", MIMETYPE_VIDEO_AVC);
- const int32_t Color = GetParam();
- if (Color >= 0) {
- cfg->setInt32("color-format", Color);
- }
- int32_t xcolor = Color == -1 ? COLOR_FormatYUV420Planar : Color;
-
- EXPECT_EQ(codec->configure(cfg, nullptr, nullptr, 0), OK);
- EXPECT_EQ(codec->getOutputFormat(&ofmt), OK);
- int32_t ocolor = -1;
- EXPECT_TRUE(ofmt->findInt32("color-format", &ocolor));
- EXPECT_EQ(ocolor, xcolor);
-
- EXPECT_EQ(codec->start(), OK);
- // assume we can submit all input before dequeuing output
- size_t frameIx = 0;
- size_t ix;
- sp<MediaCodecBuffer> buf;
- for (const FrameData &frame : avcStream_A) {
- EXPECT_EQ(codec->dequeueInputBuffer(&ix, 1000000), OK);
- EXPECT_EQ(codec->getInputBuffer(ix, &buf), OK);
- ASSERT_GE(buf->capacity(), frame.size);
- memcpy(buf->base(), frame.data, frame.size);
- EXPECT_EQ(buf->setRange(0, frame.size), OK);
- bool eos = ++frameIx == NELEM(avcStream_A);
- EXPECT_EQ(codec->queueInputBuffer(ix, 0, frame.size, frameIx * 33333,
- eos ? BUFFER_FLAG_END_OF_STREAM : 0), OK);
- }
-
- size_t offset, size;
- int64_t ts;
- uint32_t flags;
- bool mInfoFormatChangedOk = true;
- bool mInfoBuffersChangedOk = true;
- while (true) {
- status_t err = codec->dequeueOutputBuffer(&ix, &offset, &size, &ts, &flags, 1000000);
- if (err == INFO_FORMAT_CHANGED && mInfoFormatChangedOk) {
- mInfoFormatChangedOk = false;
- } else if (err == INFO_OUTPUT_BUFFERS_CHANGED && mInfoBuffersChangedOk) {
- mInfoBuffersChangedOk = false;
- } else {
- ASSERT_EQ(err, OK);
- break;
- }
- }
- EXPECT_EQ(codec->getOutputBuffer(ix, &buf), OK);
- EXPECT_EQ(codec->getOutputFormat(ix, &ofmt), OK);
- ASSERT_TRUE(ofmt->findInt32("color-format", &ocolor));
- EXPECT_EQ(ocolor, xcolor) << ofmt->debugString(8).c_str() << buf->meta()->debugString(8).c_str();
- // expect an image-data in both format and meta
- sp<ABuffer> imgBuf, imgBuf2;
- ASSERT_TRUE(ofmt->findBuffer("image-data", &imgBuf));
- ASSERT_TRUE(buf->meta()->findBuffer("image-data", &imgBuf2));
- EXPECT_EQ(imgBuf->size(), sizeof(MediaImage2));
- ASSERT_EQ(imgBuf->size(), imgBuf2->size());
- EXPECT_EQ(0, memcmp(imgBuf->data(), imgBuf2->data(), imgBuf->size()));
- MediaImage2 *img = (MediaImage2*)imgBuf->data();
- EXPECT_EQ(img->mType, img->MEDIA_IMAGE_TYPE_YUV);
- EXPECT_EQ(img->mNumPlanes, 3u);
- EXPECT_EQ(img->mWidth, 320u);
- EXPECT_EQ(img->mHeight, 240u);
- EXPECT_EQ(img->mBitDepth, 8u);
- EXPECT_EQ(img->mBitDepthAllocated, 8u);
-
- // read strides from format
- int32_t stride, vstride;
- ofmt->findInt32("stride", &stride) || ofmt->findInt32("width", &stride);
- ofmt->findInt32("slice-height", &vstride) || ofmt->findInt32("height", &vstride);
-
- EXPECT_EQ(img->mPlane[img->Y].mHorizSubsampling, 1u);
- EXPECT_EQ(img->mPlane[img->Y].mVertSubsampling, 1u);
- EXPECT_EQ(img->mPlane[img->U].mHorizSubsampling, 2u);
- EXPECT_EQ(img->mPlane[img->U].mVertSubsampling, 2u);
- EXPECT_EQ(img->mPlane[img->V].mHorizSubsampling, 2u);
- EXPECT_EQ(img->mPlane[img->V].mVertSubsampling, 2u);
-
- switch (xcolor) {
- // defined formats
- case COLOR_FormatYUV420Planar:
- case COLOR_FormatYUV420PackedPlanar:
- EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
- EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
- EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
-
- EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
- EXPECT_EQ(img->mPlane[img->U].mColInc, 1);
- EXPECT_EQ(img->mPlane[img->U].mRowInc, stride / 2);
-
- EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride * 5 / 4));
- EXPECT_EQ(img->mPlane[img->V].mColInc, 1);
- EXPECT_EQ(img->mPlane[img->V].mRowInc, stride / 2);
-
- EXPECT_GE(size, (size_t)(stride * vstride * 5 / 4 + stride / 2 * 119 + 160));
- EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
- break;
-
- case COLOR_FormatYUV420SemiPlanar:
- case COLOR_FormatYUV420PackedSemiPlanar:
- EXPECT_EQ(img->mPlane[img->Y].mOffset, 0u);
- EXPECT_EQ(img->mPlane[img->Y].mColInc, 1);
- EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
-
- EXPECT_EQ(img->mPlane[img->U].mOffset, (uint32_t)(stride * vstride));
- EXPECT_EQ(img->mPlane[img->U].mColInc, 2);
- EXPECT_EQ(img->mPlane[img->U].mRowInc, stride);
-
- EXPECT_EQ(img->mPlane[img->V].mOffset, (uint32_t)(stride * vstride + 1));
- EXPECT_EQ(img->mPlane[img->V].mColInc, 2);
- EXPECT_EQ(img->mPlane[img->V].mRowInc, stride);
-
- EXPECT_GE(size, (size_t)(stride * vstride + stride * 119 + 320));
- EXPECT_LE(size, (size_t)(stride * vstride * 3 / 2));
- break;
-
- case COLOR_FormatYUV420Flexible:
- // anything goes, but stride should match Y plane
- EXPECT_EQ(img->mPlane[img->Y].mRowInc, stride);
-
- EXPECT_GE(size,
- std::max({
- img->mPlane[img->Y].mOffset + 239 * img->mPlane[img->Y].mRowInc
- + 319 * img->mPlane[img->Y].mColInc + 1,
- img->mPlane[img->U].mOffset + 119 * img->mPlane[img->U].mRowInc
- + 159 * img->mPlane[img->U].mColInc + 1,
- img->mPlane[img->V].mOffset + 119 * img->mPlane[img->V].mRowInc
- + 159 * img->mPlane[img->V].mColInc + 1 }));
- break;
-
- default:
- break;
- }
-
- // validate all pixels
-#if 0
- fprintf(stderr, "MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }\n",
- img->mWidth, img->mHeight,
- img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
- img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
- img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
-#endif
- for (ix = 0; ix < 3; ++ix) {
- const static uint8_t expected[] = { 210, 16, 146 };
- for (uint32_t y = 0; y < img->mHeight / img->mPlane[ix].mVertSubsampling ; ++y) {
- for (uint32_t x = 0; x < img->mWidth / img->mPlane[ix].mHorizSubsampling; ++x) {
- uint8_t val = buf->data()[img->mPlane[ix].mOffset + img->mPlane[ix].mColInc * x
- + img->mPlane[ix].mRowInc * y];
- ASSERT_EQ(val, expected[ix]) << "incorrect value for plane "
- << ix << " at x=" << x << ", y=" << y;
- }
- }
- }
-}
-
-INSTANTIATE_TEST_CASE_P(InputSizes, MediaCodecByteBufferTest, ::testing::Values(
- -1,
- COLOR_FormatYUV420Planar,
- COLOR_FormatYUV420SemiPlanar,
- COLOR_FormatYUV420PackedPlanar,
- COLOR_FormatYUV420PackedSemiPlanar,
- COLOR_FormatYUV420Flexible));
-
-} // namespace android
diff --git a/media/sfplugin/tests/ReflectedParamUpdater_test.cpp b/media/sfplugin/tests/ReflectedParamUpdater_test.cpp
deleted file mode 100644
index c7db0e3..0000000
--- a/media/sfplugin/tests/ReflectedParamUpdater_test.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * 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 __C2_GENERATE_GLOBAL_VARS__
-
-#include <set>
-
-#include <gtest/gtest.h>
-
-#include <C2ParamDef.h>
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <ReflectedParamUpdater.h>
-
-namespace android {
-
-namespace {
-
-enum {
- kParamIndexTestStart = 0x1000,
- kParamIndexInt,
- kParamIndexString,
- kParamIndexComposite,
- kParamIndexFlexString,
-
- kParamIndexLong = C2Param::TYPE_INDEX_VENDOR_START,
-};
-
-typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexInt> C2IntInfo;
-typedef C2GlobalParam<C2Info, C2Int64Value, kParamIndexLong> C2LongInfo;
-
-struct C2FixedSizeStringStruct {
- char value[12];
-
- DEFINE_AND_DESCRIBE_BASE_C2STRUCT(FixedSizeString)
- C2FIELD(value, "value")
-};
-typedef C2GlobalParam<C2Info, C2FixedSizeStringStruct, kParamIndexString> C2StringInfo;
-
-struct C2CompositeStruct {
- int32_t i32;
- uint64_t u64;
- char str[12];
- uint8_t blob[8];
- uint8_t flexBlob[];
-
- C2CompositeStruct() = default;
-
- DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(Composite, flexBlob)
- C2FIELD(i32, "i32")
- C2FIELD(u64, "u64")
- C2FIELD(str, "str")
- C2FIELD(blob, "blob")
- C2FIELD(flexBlob, "flex-blob")
-};
-static_assert(C2CompositeStruct::FLEX_SIZE == 1, "");
-static_assert(_C2FlexHelper<C2CompositeStruct>::FLEX_SIZE == 1, "");
-typedef C2GlobalParam<C2Info, C2CompositeStruct, kParamIndexComposite> C2CompositeInfo;
-
-typedef C2GlobalParam<C2Info, C2StringValue, kParamIndexFlexString> C2FlexStringInfo;
-
-#define SUPPORTED_TYPES \
- C2IntInfo, \
- C2LongInfo, \
- C2StringInfo, \
- C2CompositeInfo, \
- C2FlexStringInfo
-
-template<typename... TYPES> struct describe_impl;
-template<typename T, typename... TYPES> struct describe_impl<T, TYPES...> {
- static std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex index) {
- if (index == T::CORE_INDEX) {
- return std::make_unique<C2StructDescriptor>(T::CORE_INDEX, T::FieldList());
- } else {
- return describe_impl<TYPES...>::describe(index);
- }
- }
-};
-
-template<> struct describe_impl<> {
- static std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex) {
- return nullptr;
- }
-};
-
-template<typename T> const char *GetName() { return nullptr; }
-template<> const char *GetName<C2IntInfo>() { return "int"; }
-template<> const char *GetName<C2LongInfo>() { return "long"; }
-template<> const char *GetName<C2StringInfo>() { return "string"; }
-template<> const char *GetName<C2CompositeInfo>() { return "composite"; }
-template<> const char *GetName<C2FlexStringInfo>() { return "flex-string"; }
-
-template<typename... TYPES> struct fill_descriptors_impl;
-template<typename T, typename... TYPES> struct fill_descriptors_impl<T, TYPES...> {
- static void fill(std::vector<std::shared_ptr<C2ParamDescriptor>> *vec) {
- fill_descriptors_impl<TYPES...>::fill(vec);
- vec->push_back(std::make_shared<C2ParamDescriptor>(
- T::PARAM_TYPE, C2ParamDescriptor::IS_PERSISTENT, GetName<T>()));
- }
-};
-
-template<> struct fill_descriptors_impl<> {
- static void fill(std::vector<std::shared_ptr<C2ParamDescriptor>> *) {}
-};
-
-template<typename T> T *CastParam(const std::unique_ptr<C2Param> &param) {
- return (T *)param.get();
-}
-
-class ParamReflector : public C2ParamReflector {
-public:
- ParamReflector() = default;
- ~ParamReflector() override = default;
-
- std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex paramIndex) const override {
- return describe_impl<SUPPORTED_TYPES>::describe(paramIndex);
- }
-};
-
-} // namespace
-
-class ReflectedParamUpdaterTest : public ::testing::Test {
-public:
- ReflectedParamUpdaterTest() : mReflector(new ParamReflector) {
- fill_descriptors_impl<SUPPORTED_TYPES>::fill(&mDescriptors);
- }
-
- std::shared_ptr<C2ParamReflector> mReflector;
- std::vector<std::shared_ptr<C2ParamDescriptor>> mDescriptors;
-};
-
-TEST_F(ReflectedParamUpdaterTest, SingleValueTest) {
- ReflectedParamUpdater updater;
-
- ReflectedParamUpdater::Dict msg;
- msg.emplace("int.value", int32_t(12));
- msg.emplace("vendor.long.value", int64_t(34));
-
- updater.addParamDesc(mReflector, mDescriptors);
-
- std::vector<C2Param::Index> indices;
- updater.getParamIndicesFromMessage(msg, &indices);
- EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
- EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2FlexStringInfo::PARAM_TYPE; }));
-
- std::vector<std::unique_ptr<C2Param>> params;
- params.emplace_back(new C2IntInfo);
- params.emplace_back(new C2LongInfo);
- EXPECT_EQ(0, CastParam<C2IntInfo>(params[0])->value);
- EXPECT_EQ(0, CastParam<C2LongInfo>(params[1])->value);
-
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_EQ(12, CastParam<C2IntInfo>(params[0])->value);
- EXPECT_EQ(34, CastParam<C2LongInfo>(params[1])->value);
-
- C2Value c2Value;
- int32_t int32Value = 0;
- int64_t int64Value = 0;
- msg = updater.getParams(params);
- ASSERT_EQ(1u, msg.count("int.value"));
- EXPECT_EQ(true, msg["int.value"].find(&c2Value));
- EXPECT_EQ(true, c2Value.get(&int32Value));
- EXPECT_EQ(12, int32Value);
-
- ASSERT_EQ(1u, msg.count("vendor.long.value"));
- EXPECT_EQ(true, msg["vendor.long.value"].find(&c2Value));
- EXPECT_EQ(true, c2Value.get(&int64Value));
- EXPECT_EQ(34, int64Value);
-}
-
-TEST_F(ReflectedParamUpdaterTest, StringTest) {
- ReflectedParamUpdater updater;
-
- ReflectedParamUpdater::Dict msg;
- msg.emplace("string.value", AString("56"));
- msg.emplace("flex-string.value", AString("Some string"));
- updater.addParamDesc(mReflector, mDescriptors);
-
- std::vector<C2Param::Index> indices;
- updater.getParamIndicesFromMessage(msg, &indices);
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
- EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
- EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2FlexStringInfo::PARAM_TYPE; }));
-
- std::vector<std::unique_ptr<C2Param>> params;
- params.emplace_back(new C2StringInfo);
- EXPECT_EQ(0, CastParam<C2StringInfo>(params[0])->value[0]);
- params.emplace_back(C2FlexStringInfo::AllocUnique(0));
- EXPECT_EQ(0u, CastParam<C2FlexStringInfo>(params[1])->flexCount());
- char *flexStringData = &CastParam<C2FlexStringInfo>(params[1])->m.value[0];
-
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_STREQ("56", CastParam<C2StringInfo>(params[0])->value);
- EXPECT_EQ(12u, CastParam<C2FlexStringInfo>(params[0])->flexCount());
- EXPECT_STREQ("Some string", CastParam<C2FlexStringInfo>(params[1])->m.value);
- EXPECT_NE(flexStringData, &CastParam<C2FlexStringInfo>(params[1])->m.value[0]);
- flexStringData = &CastParam<C2FlexStringInfo>(params[1])->m.value[0];
-
- // verify truncation and in-place update
- msg["string.value"] = ReflectedParamUpdater::Value(AString("1234567890ABCDE"));
- msg["flex-string.value"] = ReflectedParamUpdater::Value(AString("abc"));
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_STREQ("1234567890A", CastParam<C2StringInfo>(params[0])->value);
- EXPECT_EQ(4u, CastParam<C2FlexStringInfo>(params[1])->flexCount());
- EXPECT_STREQ("abc", CastParam<C2FlexStringInfo>(params[1])->m.value);
- EXPECT_EQ(flexStringData, &CastParam<C2FlexStringInfo>(params[1])->m.value[0]);
-
- AString strValue;
- msg = updater.getParams(params);
- ASSERT_EQ(1u, msg.count("string.value"));
- EXPECT_EQ(true, msg["string.value"].find(&strValue));
- EXPECT_STREQ("1234567890A", strValue.c_str());
-
- ASSERT_EQ(1u, msg.count("flex-string.value"));
- EXPECT_EQ(true, msg["flex-string.value"].find(&strValue));
- EXPECT_STREQ("abc", strValue.c_str());
-}
-
-TEST_F(ReflectedParamUpdaterTest, CompositeTest) {
- ReflectedParamUpdater updater;
-
- ReflectedParamUpdater::Dict msg;
- msg.emplace("composite.i32", int32_t(78));
- msg.emplace("composite.u64", int64_t(910));
- msg.emplace("composite.str", AString("1112"));
- msg.emplace("composite.blob", ABuffer::CreateAsCopy("buffer08", 8));
- msg.emplace("composite.flex-blob", ABuffer::CreateAsCopy("flex-buffer-14", 14));
-
- updater.addParamDesc(mReflector, mDescriptors);
-
- std::vector<C2Param::Index> indices;
- updater.getParamIndicesFromMessage(msg, &indices);
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
- EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
-
- std::vector<std::unique_ptr<C2Param>> params;
- params.emplace_back(C2CompositeInfo::AllocUnique(0));
- EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.i32);
- EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
- EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.str[0]);
- EXPECT_EQ(0, memcmp("\0\0\0\0\0\0\0\0", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
- EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->flexCount());
- uint8_t *flexBlobData = &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0];
-
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_EQ(78, CastParam<C2CompositeInfo>(params[0])->m.i32);
- EXPECT_EQ(910u, CastParam<C2CompositeInfo>(params[0])->m.u64);
- EXPECT_STREQ("1112", CastParam<C2CompositeInfo>(params[0])->m.str);
- EXPECT_EQ(0, memcmp("buffer08", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
- AString hex;
- hexdump(CastParam<C2CompositeInfo>(params[0])->m.blob, 8, 0, &hex);
- printf("%s\n", hex.c_str());
- ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
- EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
- EXPECT_NE(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
- flexBlobData = &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0];
-
- // test setting and zero extending shorter blob than allowed
- msg.clear();
- msg.emplace("composite.blob", ABuffer::CreateAsCopy("buf05", 5));
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_EQ(0, memcmp("buf05\0\0\0", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
- ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
- EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
- EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
-
- // test setting and trimming larger blob than allowed
- msg.clear();
- msg.emplace("composite.blob", ABuffer::CreateAsCopy("ReallyLongBuffer", 16));
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_EQ(0, memcmp("ReallyLo", CastParam<C2CompositeInfo>(params[0])->m.blob, 8));
- ASSERT_EQ(14u, CastParam<C2CompositeInfo>(params[0])->flexCount());
- EXPECT_EQ(0, memcmp("flex-buffer-14", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 14));
- EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
-
- // test trimming flex blob in-place
- msg.clear();
- msg.emplace("composite.flex-blob", ABuffer::CreateAsCopy("buf05", 5));
- updater.updateParamsFromMessage(msg, &params);
- ASSERT_EQ(5u, CastParam<C2CompositeInfo>(params[0])->flexCount());
- EXPECT_EQ(0, memcmp("buf05", CastParam<C2CompositeInfo>(params[0])->m.flexBlob, 5));
- EXPECT_EQ(flexBlobData, &CastParam<C2CompositeInfo>(params[0])->m.flexBlob[0]);
-}
-
-TEST_F(ReflectedParamUpdaterTest, CompositePartialTest) {
- ReflectedParamUpdater updater;
-
- ReflectedParamUpdater::Dict msg;
- msg.emplace("composite.i32", C2Value(1314));
- msg.emplace("composite.str", AString("1516"));
-
- updater.addParamDesc(mReflector, mDescriptors);
-
- std::vector<C2Param::Index> indices;
- updater.getParamIndicesFromMessage(msg, &indices);
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2IntInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2LongInfo::PARAM_TYPE; }));
- EXPECT_EQ(0, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2StringInfo::PARAM_TYPE; }));
- EXPECT_EQ(1, std::count_if(indices.begin(), indices.end(),
- [](const auto &value) { return (uint32_t)value == C2CompositeInfo::PARAM_TYPE; }));
-
- std::vector<std::unique_ptr<C2Param>> params;
- params.emplace_back(C2CompositeInfo::AllocUnique(12u));
- EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.i32);
- EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
- EXPECT_EQ(0, CastParam<C2CompositeInfo>(params[0])->m.str[0]);
-
- updater.updateParamsFromMessage(msg, &params);
- EXPECT_EQ(1314, CastParam<C2CompositeInfo>(params[0])->m.i32);
- EXPECT_EQ(0u, CastParam<C2CompositeInfo>(params[0])->m.u64);
- EXPECT_STREQ("1516", CastParam<C2CompositeInfo>(params[0])->m.str);
-}
-
-} // namespace android
diff --git a/media/sfplugin/utils/Android.bp b/media/sfplugin/utils/Android.bp
deleted file mode 100644
index fb5d9e4..0000000
--- a/media/sfplugin/utils/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-cc_library_shared {
- name: "libstagefright_ccodec_utils",
- vendor_available: true,
-
- srcs: [
- "Codec2BufferUtils.cpp",
- "Codec2Mapper.cpp",
- ],
-
- cflags: [
- "-Werror",
- "-Wall",
- ],
-
- export_include_dirs: [
- ".",
- ],
-
- shared_libs: [
- "libbase",
- "libcutils",
- "liblog",
- "libstagefright_codec2",
- "libstagefright_codec2_vndk",
- "libstagefright_foundation",
- "libutils",
- ],
-
- static_libs: [
- "libyuv_static",
- ],
-
- sanitize: {
- cfi: true,
- misc_undefined: [
- "unsigned-integer-overflow",
- "signed-integer-overflow",
- ],
- },
-}
diff --git a/media/sfplugin/utils/Codec2BufferUtils.cpp b/media/sfplugin/utils/Codec2BufferUtils.cpp
deleted file mode 100644
index 6b8663f..0000000
--- a/media/sfplugin/utils/Codec2BufferUtils.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * 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 "Codec2BufferUtils"
-#include <utils/Log.h>
-
-#include <libyuv.h>
-
-#include <list>
-#include <mutex>
-
-#include <media/hardware/HardwareAPI.h>
-#include <media/stagefright/foundation/AUtils.h>
-
-#include <C2Debug.h>
-
-#include "Codec2BufferUtils.h"
-
-namespace android {
-
-namespace {
-
-/**
- * A flippable, optimizable memcpy. Constructs such as (from ? src : dst) do not work as the results are
- * always const.
- */
-template<bool ToA, size_t S>
-struct MemCopier {
- template<typename A, typename B>
- inline static void copy(A *a, const B *b, size_t size) {
- __builtin_memcpy(a, b, size);
- }
-};
-
-template<size_t S>
-struct MemCopier<false, S> {
- template<typename A, typename B>
- inline static void copy(const A *a, B *b, size_t size) {
- MemCopier<true, S>::copy(b, a, size);
- }
-};
-
-/**
- * Copies between a MediaImage and a graphic view.
- *
- * \param ToMediaImage whether to copy to (or from) the MediaImage
- * \param view graphic view (could be ConstGraphicView or GraphicView depending on direction)
- * \param img MediaImage data
- * \param imgBase base of MediaImage (could be const uint8_t* or uint8_t* depending on direction)
- */
-template<bool ToMediaImage, typename View, typename ImagePixel>
-static status_t _ImageCopy(View &view, const MediaImage2 *img, ImagePixel *imgBase) {
- // TODO: more efficient copying --- e.g. copy interleaved planes together, etc.
- const C2PlanarLayout &layout = view.layout();
- const size_t bpp = divUp(img->mBitDepthAllocated, 8u);
-
- for (uint32_t i = 0; i < layout.numPlanes; ++i) {
- typename std::conditional<ToMediaImage, uint8_t, const uint8_t>::type *imgRow =
- imgBase + img->mPlane[i].mOffset;
- typename std::conditional<ToMediaImage, const uint8_t, uint8_t>::type *viewRow =
- viewRow = view.data()[i];
- const C2PlaneInfo &plane = layout.planes[i];
- if (plane.colSampling != img->mPlane[i].mHorizSubsampling
- || plane.rowSampling != img->mPlane[i].mVertSubsampling
- || plane.allocatedDepth != img->mBitDepthAllocated
- || plane.allocatedDepth < plane.bitDepth
- // MediaImage only supports MSB values
- || plane.rightShift != plane.allocatedDepth - plane.bitDepth
- || (bpp > 1 && plane.endianness != plane.NATIVE)) {
- return BAD_VALUE;
- }
-
- uint32_t planeW = img->mWidth / plane.colSampling;
- uint32_t planeH = img->mHeight / plane.rowSampling;
-
- bool canCopyByRow = (plane.colInc == 1) && (img->mPlane[i].mColInc == 1);
- bool canCopyByPlane = canCopyByRow && (plane.rowInc == img->mPlane[i].mRowInc);
- if (canCopyByPlane) {
- MemCopier<ToMediaImage, 0>::copy(imgRow, viewRow, plane.rowInc * planeH);
- } else if (canCopyByRow) {
- for (uint32_t row = 0; row < planeH; ++row) {
- MemCopier<ToMediaImage, 0>::copy(
- imgRow, viewRow, std::min(plane.rowInc, img->mPlane[i].mRowInc));
- imgRow += img->mPlane[i].mRowInc;
- viewRow += plane.rowInc;
- }
- } else {
- for (uint32_t row = 0; row < planeH; ++row) {
- decltype(imgRow) imgPtr = imgRow;
- decltype(viewRow) viewPtr = viewRow;
- for (uint32_t col = 0; col < planeW; ++col) {
- MemCopier<ToMediaImage, 0>::copy(imgPtr, viewPtr, bpp);
- imgPtr += img->mPlane[i].mColInc;
- viewPtr += plane.colInc;
- }
- imgRow += img->mPlane[i].mRowInc;
- viewRow += plane.rowInc;
- }
- }
- }
- return OK;
-}
-
-} // namespace
-
-status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view) {
- if (view.width() != img->mWidth || view.height() != img->mHeight) {
- return BAD_VALUE;
- }
- if ((IsNV12(view) && IsI420(img)) || (IsI420(view) && IsNV12(img))) {
- // Take shortcuts to use libyuv functions between NV12 and I420 conversion.
- const uint8_t* src_y = view.data()[0];
- const uint8_t* src_u = view.data()[1];
- const uint8_t* src_v = view.data()[2];
- int32_t src_stride_y = view.layout().planes[0].rowInc;
- int32_t src_stride_u = view.layout().planes[1].rowInc;
- int32_t src_stride_v = view.layout().planes[2].rowInc;
- uint8_t* dst_y = imgBase + img->mPlane[0].mOffset;
- uint8_t* dst_u = imgBase + img->mPlane[1].mOffset;
- uint8_t* dst_v = imgBase + img->mPlane[2].mOffset;
- int32_t dst_stride_y = img->mPlane[0].mRowInc;
- int32_t dst_stride_u = img->mPlane[1].mRowInc;
- int32_t dst_stride_v = img->mPlane[2].mRowInc;
- if (IsNV12(view) && IsI420(img)) {
- if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
- dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
- view.height())) {
- return OK;
- }
- } else {
- if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
- dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
- view.height())) {
- return OK;
- }
- }
- }
- return _ImageCopy<true>(view, img, imgBase);
-}
-
-status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img) {
- if (view.width() != img->mWidth || view.height() != img->mHeight) {
- return BAD_VALUE;
- }
- if ((IsNV12(img) && IsI420(view)) || (IsI420(img) && IsNV12(view))) {
- // Take shortcuts to use libyuv functions between NV12 and I420 conversion.
- const uint8_t* src_y = imgBase + img->mPlane[0].mOffset;
- const uint8_t* src_u = imgBase + img->mPlane[1].mOffset;
- const uint8_t* src_v = imgBase + img->mPlane[2].mOffset;
- int32_t src_stride_y = img->mPlane[0].mRowInc;
- int32_t src_stride_u = img->mPlane[1].mRowInc;
- int32_t src_stride_v = img->mPlane[2].mRowInc;
- uint8_t* dst_y = view.data()[0];
- uint8_t* dst_u = view.data()[1];
- uint8_t* dst_v = view.data()[2];
- int32_t dst_stride_y = view.layout().planes[0].rowInc;
- int32_t dst_stride_u = view.layout().planes[1].rowInc;
- int32_t dst_stride_v = view.layout().planes[2].rowInc;
- if (IsNV12(img) && IsI420(view)) {
- if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
- dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
- view.height())) {
- return OK;
- }
- } else {
- if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
- dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
- view.height())) {
- return OK;
- }
- }
- }
- return _ImageCopy<false>(view, img, imgBase);
-}
-
-bool IsYUV420(const C2GraphicView &view) {
- const C2PlanarLayout &layout = view.layout();
- return (layout.numPlanes == 3
- && layout.type == C2PlanarLayout::TYPE_YUV
- && layout.planes[layout.PLANE_Y].channel == C2PlaneInfo::CHANNEL_Y
- && layout.planes[layout.PLANE_Y].allocatedDepth == 8
- && layout.planes[layout.PLANE_Y].bitDepth == 8
- && layout.planes[layout.PLANE_Y].rightShift == 0
- && layout.planes[layout.PLANE_Y].colSampling == 1
- && layout.planes[layout.PLANE_Y].rowSampling == 1
- && layout.planes[layout.PLANE_U].channel == C2PlaneInfo::CHANNEL_CB
- && layout.planes[layout.PLANE_U].allocatedDepth == 8
- && layout.planes[layout.PLANE_U].bitDepth == 8
- && layout.planes[layout.PLANE_U].rightShift == 0
- && layout.planes[layout.PLANE_U].colSampling == 2
- && layout.planes[layout.PLANE_U].rowSampling == 2
- && layout.planes[layout.PLANE_V].channel == C2PlaneInfo::CHANNEL_CR
- && layout.planes[layout.PLANE_V].allocatedDepth == 8
- && layout.planes[layout.PLANE_V].bitDepth == 8
- && layout.planes[layout.PLANE_V].rightShift == 0
- && layout.planes[layout.PLANE_V].colSampling == 2
- && layout.planes[layout.PLANE_V].rowSampling == 2);
-}
-
-bool IsNV12(const C2GraphicView &view) {
- if (!IsYUV420(view)) {
- return false;
- }
- const C2PlanarLayout &layout = view.layout();
- return (layout.rootPlanes == 2
- && layout.planes[layout.PLANE_U].colInc == 2
- && layout.planes[layout.PLANE_U].rootIx == layout.PLANE_U
- && layout.planes[layout.PLANE_U].offset == 0
- && layout.planes[layout.PLANE_V].colInc == 2
- && layout.planes[layout.PLANE_V].rootIx == layout.PLANE_U
- && layout.planes[layout.PLANE_V].offset == 1);
-}
-
-bool IsI420(const C2GraphicView &view) {
- if (!IsYUV420(view)) {
- return false;
- }
- const C2PlanarLayout &layout = view.layout();
- return (layout.rootPlanes == 3
- && layout.planes[layout.PLANE_U].colInc == 1
- && layout.planes[layout.PLANE_U].rootIx == layout.PLANE_U
- && layout.planes[layout.PLANE_U].offset == 0
- && layout.planes[layout.PLANE_V].colInc == 1
- && layout.planes[layout.PLANE_V].rootIx == layout.PLANE_V
- && layout.planes[layout.PLANE_V].offset == 0);
-}
-
-bool IsYUV420(const MediaImage2 *img) {
- return (img->mType == MediaImage2::MEDIA_IMAGE_TYPE_YUV
- && img->mNumPlanes == 3
- && img->mBitDepth == 8
- && img->mBitDepthAllocated == 8
- && img->mPlane[0].mHorizSubsampling == 1
- && img->mPlane[0].mVertSubsampling == 1
- && img->mPlane[1].mHorizSubsampling == 2
- && img->mPlane[1].mVertSubsampling == 2
- && img->mPlane[2].mHorizSubsampling == 2
- && img->mPlane[2].mVertSubsampling == 2);
-}
-
-bool IsNV12(const MediaImage2 *img) {
- if (!IsYUV420(img)) {
- return false;
- }
- return (img->mPlane[1].mColInc == 2
- && img->mPlane[2].mColInc == 2
- && (img->mPlane[2].mOffset - img->mPlane[1].mOffset == 1));
-}
-
-bool IsI420(const MediaImage2 *img) {
- if (!IsYUV420(img)) {
- return false;
- }
- return (img->mPlane[1].mColInc == 1
- && img->mPlane[2].mColInc == 1
- && img->mPlane[2].mOffset > img->mPlane[1].mOffset);
-}
-
-MediaImage2 CreateYUV420PlanarMediaImage2(
- uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride) {
- return MediaImage2 {
- .mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV,
- .mNumPlanes = 3,
- .mWidth = width,
- .mHeight = height,
- .mBitDepth = 8,
- .mBitDepthAllocated = 8,
- .mPlane = {
- {
- .mOffset = 0,
- .mColInc = 1,
- .mRowInc = (int32_t)stride,
- .mHorizSubsampling = 1,
- .mVertSubsampling = 1,
- },
- {
- .mOffset = stride * vstride,
- .mColInc = 1,
- .mRowInc = (int32_t)stride / 2,
- .mHorizSubsampling = 2,
- .mVertSubsampling = 2,
- },
- {
- .mOffset = stride * vstride * 5 / 4,
- .mColInc = 1,
- .mRowInc = (int32_t)stride / 2,
- .mHorizSubsampling = 2,
- .mVertSubsampling = 2,
- }
- },
- };
-}
-
-MediaImage2 CreateYUV420SemiPlanarMediaImage2(
- uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride) {
- return MediaImage2 {
- .mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV,
- .mNumPlanes = 3,
- .mWidth = width,
- .mHeight = height,
- .mBitDepth = 8,
- .mBitDepthAllocated = 8,
- .mPlane = {
- {
- .mOffset = 0,
- .mColInc = 1,
- .mRowInc = (int32_t)stride,
- .mHorizSubsampling = 1,
- .mVertSubsampling = 1,
- },
- {
- .mOffset = stride * vstride,
- .mColInc = 2,
- .mRowInc = (int32_t)stride,
- .mHorizSubsampling = 2,
- .mVertSubsampling = 2,
- },
- {
- .mOffset = stride * vstride + 1,
- .mColInc = 2,
- .mRowInc = (int32_t)stride,
- .mHorizSubsampling = 2,
- .mVertSubsampling = 2,
- }
- },
- };
-}
-
-status_t ConvertRGBToPlanarYUV(
- uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
- const C2GraphicView &src) {
- CHECK(dstY != nullptr);
- CHECK((src.width() & 1) == 0);
- CHECK((src.height() & 1) == 0);
-
- if (dstStride * dstVStride * 3 / 2 > bufferSize) {
- ALOGD("conversion buffer is too small for converting from RGB to YUV");
- return NO_MEMORY;
- }
-
- uint8_t *dstU = dstY + dstStride * dstVStride;
- uint8_t *dstV = dstU + (dstStride >> 1) * (dstVStride >> 1);
-
- const C2PlanarLayout &layout = src.layout();
- const uint8_t *pRed = src.data()[C2PlanarLayout::PLANE_R];
- const uint8_t *pGreen = src.data()[C2PlanarLayout::PLANE_G];
- const uint8_t *pBlue = src.data()[C2PlanarLayout::PLANE_B];
-
-#define CLIP3(x,y,z) (((z) < (x)) ? (x) : (((z) > (y)) ? (y) : (z)))
- for (size_t y = 0; y < src.height(); ++y) {
- for (size_t x = 0; x < src.width(); ++x) {
- uint8_t red = *pRed;
- uint8_t green = *pGreen;
- uint8_t blue = *pBlue;
-
- // using ITU-R BT.601 conversion matrix
- unsigned luma =
- CLIP3(0, (((red * 66 + green * 129 + blue * 25) >> 8) + 16), 255);
-
- dstY[x] = luma;
-
- if ((x & 1) == 0 && (y & 1) == 0) {
- unsigned U =
- CLIP3(0, (((-red * 38 - green * 74 + blue * 112) >> 8) + 128), 255);
-
- unsigned V =
- CLIP3(0, (((red * 112 - green * 94 - blue * 18) >> 8) + 128), 255);
-
- dstU[x >> 1] = U;
- dstV[x >> 1] = V;
- }
- pRed += layout.planes[C2PlanarLayout::PLANE_R].colInc;
- pGreen += layout.planes[C2PlanarLayout::PLANE_G].colInc;
- pBlue += layout.planes[C2PlanarLayout::PLANE_B].colInc;
- }
-
- if ((y & 1) == 0) {
- dstU += dstStride >> 1;
- dstV += dstStride >> 1;
- }
-
- pRed -= layout.planes[C2PlanarLayout::PLANE_R].colInc * src.width();
- pGreen -= layout.planes[C2PlanarLayout::PLANE_G].colInc * src.width();
- pBlue -= layout.planes[C2PlanarLayout::PLANE_B].colInc * src.width();
- pRed += layout.planes[C2PlanarLayout::PLANE_R].rowInc;
- pGreen += layout.planes[C2PlanarLayout::PLANE_G].rowInc;
- pBlue += layout.planes[C2PlanarLayout::PLANE_B].rowInc;
-
- dstY += dstStride;
- }
- return OK;
-}
-
-namespace {
-
-/**
- * A block of raw allocated memory.
- */
-struct MemoryBlockPoolBlock {
- MemoryBlockPoolBlock(size_t size)
- : mData(new uint8_t[size]), mSize(mData ? size : 0) { }
-
- ~MemoryBlockPoolBlock() {
- delete[] mData;
- }
-
- const uint8_t *data() const {
- return mData;
- }
-
- size_t size() const {
- return mSize;
- }
-
- C2_DO_NOT_COPY(MemoryBlockPoolBlock);
-
-private:
- uint8_t *mData;
- size_t mSize;
-};
-
-/**
- * A simple raw memory block pool implementation.
- */
-struct MemoryBlockPoolImpl {
- void release(std::list<MemoryBlockPoolBlock>::const_iterator block) {
- std::lock_guard<std::mutex> lock(mMutex);
- // return block to free blocks if it is the current size; otherwise, discard
- if (block->size() == mCurrentSize) {
- mFreeBlocks.splice(mFreeBlocks.begin(), mBlocksInUse, block);
- } else {
- mBlocksInUse.erase(block);
- }
- }
-
- std::list<MemoryBlockPoolBlock>::const_iterator fetch(size_t size) {
- std::lock_guard<std::mutex> lock(mMutex);
- mFreeBlocks.remove_if([size](const MemoryBlockPoolBlock &block) -> bool {
- return block.size() != size;
- });
- mCurrentSize = size;
- if (mFreeBlocks.empty()) {
- mBlocksInUse.emplace_front(size);
- } else {
- mBlocksInUse.splice(mBlocksInUse.begin(), mFreeBlocks, mFreeBlocks.begin());
- }
- return mBlocksInUse.begin();
- }
-
- MemoryBlockPoolImpl() = default;
-
- C2_DO_NOT_COPY(MemoryBlockPoolImpl);
-
-private:
- std::mutex mMutex;
- std::list<MemoryBlockPoolBlock> mFreeBlocks;
- std::list<MemoryBlockPoolBlock> mBlocksInUse;
- size_t mCurrentSize;
-};
-
-} // namespace
-
-struct MemoryBlockPool::Impl : MemoryBlockPoolImpl {
-};
-
-struct MemoryBlock::Impl {
- Impl(std::list<MemoryBlockPoolBlock>::const_iterator block,
- std::shared_ptr<MemoryBlockPoolImpl> pool)
- : mBlock(block), mPool(pool) {
- }
-
- ~Impl() {
- mPool->release(mBlock);
- }
-
- const uint8_t *data() const {
- return mBlock->data();
- }
-
- size_t size() const {
- return mBlock->size();
- }
-
-private:
- std::list<MemoryBlockPoolBlock>::const_iterator mBlock;
- std::shared_ptr<MemoryBlockPoolImpl> mPool;
-};
-
-MemoryBlock MemoryBlockPool::fetch(size_t size) {
- std::list<MemoryBlockPoolBlock>::const_iterator poolBlock = mImpl->fetch(size);
- return MemoryBlock(std::make_shared<MemoryBlock::Impl>(
- poolBlock, std::static_pointer_cast<MemoryBlockPoolImpl>(mImpl)));
-}
-
-MemoryBlockPool::MemoryBlockPool()
- : mImpl(std::make_shared<MemoryBlockPool::Impl>()) {
-}
-
-MemoryBlock::MemoryBlock(std::shared_ptr<MemoryBlock::Impl> impl)
- : mImpl(impl) {
-}
-
-MemoryBlock::MemoryBlock() = default;
-
-MemoryBlock::~MemoryBlock() = default;
-
-const uint8_t* MemoryBlock::data() const {
- return mImpl ? mImpl->data() : nullptr;
-}
-
-size_t MemoryBlock::size() const {
- return mImpl ? mImpl->size() : 0;
-}
-
-MemoryBlock MemoryBlock::Allocate(size_t size) {
- return MemoryBlockPool().fetch(size);
-}
-
-} // namespace android
diff --git a/media/sfplugin/utils/Codec2BufferUtils.h b/media/sfplugin/utils/Codec2BufferUtils.h
deleted file mode 100644
index afadf00..0000000
--- a/media/sfplugin/utils/Codec2BufferUtils.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef CODEC2_BUFFER_UTILS_H_
-#define CODEC2_BUFFER_UTILS_H_
-
-#include <C2Buffer.h>
-#include <C2ParamDef.h>
-
-#include <media/hardware/VideoAPI.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-/**
- * Converts an RGB view to planar YUV 420 media image.
- *
- * \param dstY pointer to media image buffer
- * \param dstStride stride in bytes
- * \param dstVStride vertical stride in pixels
- * \param bufferSize media image buffer size
- * \param src source image
- *
- * \retval NO_MEMORY media image is too small
- * \retval OK on success
- */
-status_t ConvertRGBToPlanarYUV(
- uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
- const C2GraphicView &src);
-
-/**
- * Returns a planar YUV 420 8-bit media image descriptor.
- *
- * \param width width of image in pixels
- * \param height height of image in pixels
- * \param stride stride of image in pixels
- * \param vstride vertical stride of image in pixels
- */
-MediaImage2 CreateYUV420PlanarMediaImage2(
- uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
-
-/**
- * Returns a semiplanar YUV 420 8-bit media image descriptor.
- *
- * \param width width of image in pixels
- * \param height height of image in pixels
- * \param stride stride of image in pixels
- * \param vstride vertical stride of image in pixels
- */
-MediaImage2 CreateYUV420SemiPlanarMediaImage2(
- uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
-
-/**
- * Copies a graphic view into a media image.
- *
- * \param imgBase base of MediaImage
- * \param img MediaImage data
- * \param view graphic view
- *
- * \return OK on success
- */
-status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
-
-/**
- * Copies a media image into a graphic view.
- *
- * \param view graphic view
- * \param imgBase base of MediaImage
- * \param img MediaImage data
- *
- * \return OK on success
- */
-status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
-
-/**
- * Returns true iff a view has a YUV 420 888 layout.
- */
-bool IsYUV420(const C2GraphicView &view);
-
-/**
- * Returns true iff a view has a NV12 layout.
- */
-bool IsNV12(const C2GraphicView &view);
-
-/**
- * Returns true iff a view has a I420 layout.
- */
-bool IsI420(const C2GraphicView &view);
-
-/**
- * Returns true iff a MediaImage2 has a YUV 420 888 layout.
- */
-bool IsYUV420(const MediaImage2 *img);
-
-/**
- * Returns true iff a MediaImage2 has a NV12 layout.
- */
-bool IsNV12(const MediaImage2 *img);
-
-/**
- * Returns true iff a MediaImage2 has a I420 layout.
- */
-bool IsI420(const MediaImage2 *img);
-
-/**
- * A raw memory block to use for internal buffers.
- *
- * TODO: replace this with C2LinearBlocks from a private C2BlockPool
- */
-struct MemoryBlock : public C2MemoryBlock<uint8_t> {
- virtual const uint8_t* data() const override;
- virtual size_t size() const override;
-
- inline uint8_t *data() {
- return const_cast<uint8_t*>(const_cast<const MemoryBlock*>(this)->data());
- }
-
- // allocates an unmanaged block (not in a pool)
- static MemoryBlock Allocate(size_t);
-
- // memory block with no actual memory (size is 0, data is null)
- MemoryBlock();
-
- struct Impl;
- MemoryBlock(std::shared_ptr<Impl> impl);
- virtual ~MemoryBlock();
-
-private:
- std::shared_ptr<Impl> mImpl;
-};
-
-/**
- * A raw memory mini-pool.
- */
-struct MemoryBlockPool {
- /**
- * Fetches a block with a given size.
- *
- * \param size size in bytes
- */
- MemoryBlock fetch(size_t size);
-
- MemoryBlockPool();
- ~MemoryBlockPool() = default;
-
-private:
- struct Impl;
- std::shared_ptr<Impl> mImpl;
-};
-
-} // namespace android
-
-#endif // CODEC2_BUFFER_UTILS_H_
diff --git a/media/sfplugin/utils/Codec2Mapper.cpp b/media/sfplugin/utils/Codec2Mapper.cpp
deleted file mode 100644
index 97e17e8..0000000
--- a/media/sfplugin/utils/Codec2Mapper.cpp
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * 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 "Codec2Mapper"
-#include <utils/Log.h>
-
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/SurfaceUtils.h>
-#include <media/stagefright/foundation/ALookup.h>
-#include <media/stagefright/foundation/ColorUtils.h>
-#include <media/stagefright/foundation/MediaDefs.h>
-
-#include <stdint.h> // for INT32_MAX
-
-#include "Codec2Mapper.h"
-
-using namespace android;
-
-namespace {
-
-ALookup<C2Config::profile_t, int32_t> sAacProfiles = {
- { C2Config::PROFILE_AAC_LC, AACObjectLC },
- { C2Config::PROFILE_AAC_MAIN, AACObjectMain },
- { C2Config::PROFILE_AAC_SSR, AACObjectSSR },
- { C2Config::PROFILE_AAC_LTP, AACObjectLTP },
- { C2Config::PROFILE_AAC_HE, AACObjectHE },
- { C2Config::PROFILE_AAC_SCALABLE, AACObjectScalable },
- { C2Config::PROFILE_AAC_ER_LC, AACObjectERLC },
- { C2Config::PROFILE_AAC_ER_SCALABLE, AACObjectERScalable },
- { C2Config::PROFILE_AAC_LD, AACObjectLD },
- { C2Config::PROFILE_AAC_HE_PS, AACObjectHE_PS },
- { C2Config::PROFILE_AAC_ELD, AACObjectELD },
- { C2Config::PROFILE_AAC_XHE, AACObjectXHE },
-};
-
-ALookup<C2Config::level_t, int32_t> sAvcLevels = {
- { C2Config::LEVEL_AVC_1, AVCLevel1 },
- { C2Config::LEVEL_AVC_1B, AVCLevel1b },
- { C2Config::LEVEL_AVC_1_1, AVCLevel11 },
- { C2Config::LEVEL_AVC_1_2, AVCLevel12 },
- { C2Config::LEVEL_AVC_1_3, AVCLevel13 },
- { C2Config::LEVEL_AVC_2, AVCLevel2 },
- { C2Config::LEVEL_AVC_2_1, AVCLevel21 },
- { C2Config::LEVEL_AVC_2_2, AVCLevel22 },
- { C2Config::LEVEL_AVC_3, AVCLevel3 },
- { C2Config::LEVEL_AVC_3_1, AVCLevel31 },
- { C2Config::LEVEL_AVC_3_2, AVCLevel32 },
- { C2Config::LEVEL_AVC_4, AVCLevel4 },
- { C2Config::LEVEL_AVC_4_1, AVCLevel41 },
- { C2Config::LEVEL_AVC_4_2, AVCLevel42 },
- { C2Config::LEVEL_AVC_5, AVCLevel5 },
- { C2Config::LEVEL_AVC_5_1, AVCLevel51 },
- { C2Config::LEVEL_AVC_5_2, AVCLevel52 },
-
-};
-
-ALookup<C2Config::profile_t, int32_t> sAvcProfiles = {
- // treat restricted profiles as full profile if there is no equivalent - which works for
- // decoders, but not for encoders
- { C2Config::PROFILE_AVC_BASELINE, AVCProfileBaseline },
- { C2Config::PROFILE_AVC_CONSTRAINED_BASELINE, AVCProfileConstrainedBaseline },
- { C2Config::PROFILE_AVC_MAIN, AVCProfileMain },
- { C2Config::PROFILE_AVC_EXTENDED, AVCProfileExtended },
- { C2Config::PROFILE_AVC_HIGH, AVCProfileHigh },
- { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH, AVCProfileHigh },
- { C2Config::PROFILE_AVC_CONSTRAINED_HIGH, AVCProfileConstrainedHigh },
- { C2Config::PROFILE_AVC_HIGH_10, AVCProfileHigh10 },
- { C2Config::PROFILE_AVC_PROGRESSIVE_HIGH_10, AVCProfileHigh10 },
- { C2Config::PROFILE_AVC_HIGH_422, AVCProfileHigh422 },
- { C2Config::PROFILE_AVC_HIGH_444_PREDICTIVE, AVCProfileHigh444 },
- { C2Config::PROFILE_AVC_HIGH_10_INTRA, AVCProfileHigh10 },
- { C2Config::PROFILE_AVC_HIGH_422_INTRA, AVCProfileHigh422 },
- { C2Config::PROFILE_AVC_HIGH_444_INTRA, AVCProfileHigh444 },
- { C2Config::PROFILE_AVC_CAVLC_444_INTRA, AVCProfileHigh444 },
-};
-
-ALookup<C2Config::bitrate_mode_t, int32_t> sBitrateModes = {
- { C2Config::BITRATE_CONST, BITRATE_MODE_CBR },
- { C2Config::BITRATE_VARIABLE, BITRATE_MODE_VBR },
- { C2Config::BITRATE_IGNORE, BITRATE_MODE_CQ },
-};
-
-ALookup<C2Color::matrix_t, ColorAspects::MatrixCoeffs> sColorMatricesSf = {
- { C2Color::MATRIX_UNSPECIFIED, ColorAspects::MatrixUnspecified },
- { C2Color::MATRIX_BT709, ColorAspects::MatrixBT709_5 },
- { C2Color::MATRIX_FCC47_73_682, ColorAspects::MatrixBT470_6M },
- { C2Color::MATRIX_BT601, ColorAspects::MatrixBT601_6 },
- { C2Color::MATRIX_SMPTE240M, ColorAspects::MatrixSMPTE240M },
- { C2Color::MATRIX_BT2020, ColorAspects::MatrixBT2020 },
- { C2Color::MATRIX_BT2020_CONSTANT, ColorAspects::MatrixBT2020Constant },
- { C2Color::MATRIX_OTHER, ColorAspects::MatrixOther },
-};
-
-ALookup<C2Color::primaries_t, ColorAspects::Primaries> sColorPrimariesSf = {
- { C2Color::PRIMARIES_UNSPECIFIED, ColorAspects::PrimariesUnspecified },
- { C2Color::PRIMARIES_BT709, ColorAspects::PrimariesBT709_5 },
- { C2Color::PRIMARIES_BT470_M, ColorAspects::PrimariesBT470_6M },
- { C2Color::PRIMARIES_BT601_625, ColorAspects::PrimariesBT601_6_625 },
- { C2Color::PRIMARIES_BT601_525, ColorAspects::PrimariesBT601_6_525 },
- { C2Color::PRIMARIES_GENERIC_FILM, ColorAspects::PrimariesGenericFilm },
- { C2Color::PRIMARIES_BT2020, ColorAspects::PrimariesBT2020 },
-// { C2Color::PRIMARIES_RP431, ColorAspects::Primaries... },
-// { C2Color::PRIMARIES_EG432, ColorAspects::Primaries... },
-// { C2Color::PRIMARIES_EBU3213, ColorAspects::Primaries... },
- { C2Color::PRIMARIES_OTHER, ColorAspects::PrimariesOther },
-};
-
-ALookup<C2Color::range_t, int32_t> sColorRanges = {
- { C2Color::RANGE_FULL, COLOR_RANGE_FULL },
- { C2Color::RANGE_LIMITED, COLOR_RANGE_LIMITED },
-};
-
-ALookup<C2Color::range_t, ColorAspects::Range> sColorRangesSf = {
- { C2Color::RANGE_UNSPECIFIED, ColorAspects::RangeUnspecified },
- { C2Color::RANGE_FULL, ColorAspects::RangeFull },
- { C2Color::RANGE_LIMITED, ColorAspects::RangeLimited },
- { C2Color::RANGE_OTHER, ColorAspects::RangeOther },
-};
-
-ALookup<C2Color::transfer_t, int32_t> sColorTransfers = {
- { C2Color::TRANSFER_LINEAR, COLOR_TRANSFER_LINEAR },
- { C2Color::TRANSFER_170M, COLOR_TRANSFER_SDR_VIDEO },
- { C2Color::TRANSFER_ST2084, COLOR_TRANSFER_ST2084 },
- { C2Color::TRANSFER_HLG, COLOR_TRANSFER_HLG },
-};
-
-ALookup<C2Color::transfer_t, ColorAspects::Transfer> sColorTransfersSf = {
- { C2Color::TRANSFER_UNSPECIFIED, ColorAspects::TransferUnspecified },
- { C2Color::TRANSFER_LINEAR, ColorAspects::TransferLinear },
- { C2Color::TRANSFER_SRGB, ColorAspects::TransferSRGB },
- { C2Color::TRANSFER_170M, ColorAspects::TransferSMPTE170M },
- { C2Color::TRANSFER_GAMMA22, ColorAspects::TransferGamma22 },
- { C2Color::TRANSFER_GAMMA28, ColorAspects::TransferGamma28 },
- { C2Color::TRANSFER_ST2084, ColorAspects::TransferST2084 },
- { C2Color::TRANSFER_HLG, ColorAspects::TransferHLG },
- { C2Color::TRANSFER_240M, ColorAspects::TransferSMPTE240M },
- { C2Color::TRANSFER_XVYCC, ColorAspects::TransferXvYCC },
- { C2Color::TRANSFER_BT1361, ColorAspects::TransferBT1361 },
- { C2Color::TRANSFER_ST428, ColorAspects::TransferST428 },
- { C2Color::TRANSFER_OTHER, ColorAspects::TransferOther },
-};
-
-ALookup<C2Config::level_t, int32_t> sDolbyVisionLevels = {
- { C2Config::LEVEL_DV_MAIN_HD_24, DolbyVisionLevelHd24 },
- { C2Config::LEVEL_DV_MAIN_HD_30, DolbyVisionLevelHd30 },
- { C2Config::LEVEL_DV_MAIN_FHD_24, DolbyVisionLevelFhd24 },
- { C2Config::LEVEL_DV_MAIN_FHD_30, DolbyVisionLevelFhd30 },
- { C2Config::LEVEL_DV_MAIN_FHD_60, DolbyVisionLevelFhd60 },
- { C2Config::LEVEL_DV_MAIN_UHD_24, DolbyVisionLevelUhd24 },
- { C2Config::LEVEL_DV_MAIN_UHD_30, DolbyVisionLevelUhd30 },
- { C2Config::LEVEL_DV_MAIN_UHD_48, DolbyVisionLevelUhd48 },
- { C2Config::LEVEL_DV_MAIN_UHD_60, DolbyVisionLevelUhd60 },
-
- // high tiers are not yet supported on android, for now map them to main tier
- { C2Config::LEVEL_DV_HIGH_HD_24, DolbyVisionLevelHd24 },
- { C2Config::LEVEL_DV_HIGH_HD_30, DolbyVisionLevelHd30 },
- { C2Config::LEVEL_DV_HIGH_FHD_24, DolbyVisionLevelFhd24 },
- { C2Config::LEVEL_DV_HIGH_FHD_30, DolbyVisionLevelFhd30 },
- { C2Config::LEVEL_DV_HIGH_FHD_60, DolbyVisionLevelFhd60 },
- { C2Config::LEVEL_DV_HIGH_UHD_24, DolbyVisionLevelUhd24 },
- { C2Config::LEVEL_DV_HIGH_UHD_30, DolbyVisionLevelUhd30 },
- { C2Config::LEVEL_DV_HIGH_UHD_48, DolbyVisionLevelUhd48 },
- { C2Config::LEVEL_DV_HIGH_UHD_60, DolbyVisionLevelUhd60 },
-};
-
-ALookup<C2Config::profile_t, int32_t> sDolbyVisionProfiles = {
- { C2Config::PROFILE_DV_AV_PER, DolbyVisionProfileDvavPer },
- { C2Config::PROFILE_DV_AV_PEN, DolbyVisionProfileDvavPen },
- { C2Config::PROFILE_DV_HE_DER, DolbyVisionProfileDvheDer },
- { C2Config::PROFILE_DV_HE_DEN, DolbyVisionProfileDvheDen },
- { C2Config::PROFILE_DV_HE_04, DolbyVisionProfileDvheDtr },
- { C2Config::PROFILE_DV_HE_05, DolbyVisionProfileDvheStn },
- { C2Config::PROFILE_DV_HE_DTH, DolbyVisionProfileDvheDth },
- { C2Config::PROFILE_DV_HE_07, DolbyVisionProfileDvheDtb },
- { C2Config::PROFILE_DV_HE_08, DolbyVisionProfileDvheSt },
- { C2Config::PROFILE_DV_AV_09, DolbyVisionProfileDvavSe },
-};
-
-ALookup<C2Config::level_t, int32_t> sH263Levels = {
- { C2Config::LEVEL_H263_10, H263Level10 },
- { C2Config::LEVEL_H263_20, H263Level20 },
- { C2Config::LEVEL_H263_30, H263Level30 },
- { C2Config::LEVEL_H263_40, H263Level40 },
- { C2Config::LEVEL_H263_45, H263Level45 },
- { C2Config::LEVEL_H263_50, H263Level50 },
- { C2Config::LEVEL_H263_60, H263Level60 },
- { C2Config::LEVEL_H263_70, H263Level70 },
-};
-
-ALookup<C2Config::profile_t, int32_t> sH263Profiles = {
- { C2Config::PROFILE_H263_BASELINE, H263ProfileBaseline },
- { C2Config::PROFILE_H263_H320, H263ProfileH320Coding },
- { C2Config::PROFILE_H263_V1BC, H263ProfileBackwardCompatible },
- { C2Config::PROFILE_H263_ISWV2, H263ProfileISWV2 },
- { C2Config::PROFILE_H263_ISWV3, H263ProfileISWV3 },
- { C2Config::PROFILE_H263_HIGH_COMPRESSION, H263ProfileHighCompression },
- { C2Config::PROFILE_H263_INTERNET, H263ProfileInternet },
- { C2Config::PROFILE_H263_INTERLACE, H263ProfileInterlace },
- { C2Config::PROFILE_H263_HIGH_LATENCY, H263ProfileHighLatency },
-};
-
-ALookup<C2Config::level_t, int32_t> sHevcLevels = {
- { C2Config::LEVEL_HEVC_MAIN_1, HEVCMainTierLevel1 },
- { C2Config::LEVEL_HEVC_MAIN_2, HEVCMainTierLevel2 },
- { C2Config::LEVEL_HEVC_MAIN_2_1, HEVCMainTierLevel21 },
- { C2Config::LEVEL_HEVC_MAIN_3, HEVCMainTierLevel3 },
- { C2Config::LEVEL_HEVC_MAIN_3_1, HEVCMainTierLevel31 },
- { C2Config::LEVEL_HEVC_MAIN_4, HEVCMainTierLevel4 },
- { C2Config::LEVEL_HEVC_MAIN_4_1, HEVCMainTierLevel41 },
- { C2Config::LEVEL_HEVC_MAIN_5, HEVCMainTierLevel5 },
- { C2Config::LEVEL_HEVC_MAIN_5_1, HEVCMainTierLevel51 },
- { C2Config::LEVEL_HEVC_MAIN_5_2, HEVCMainTierLevel52 },
- { C2Config::LEVEL_HEVC_MAIN_6, HEVCMainTierLevel6 },
- { C2Config::LEVEL_HEVC_MAIN_6_1, HEVCMainTierLevel61 },
- { C2Config::LEVEL_HEVC_MAIN_6_2, HEVCMainTierLevel62 },
-
- { C2Config::LEVEL_HEVC_HIGH_4, HEVCHighTierLevel4 },
- { C2Config::LEVEL_HEVC_HIGH_4_1, HEVCHighTierLevel41 },
- { C2Config::LEVEL_HEVC_HIGH_5, HEVCHighTierLevel5 },
- { C2Config::LEVEL_HEVC_HIGH_5_1, HEVCHighTierLevel51 },
- { C2Config::LEVEL_HEVC_HIGH_5_2, HEVCHighTierLevel52 },
- { C2Config::LEVEL_HEVC_HIGH_6, HEVCHighTierLevel6 },
- { C2Config::LEVEL_HEVC_HIGH_6_1, HEVCHighTierLevel61 },
- { C2Config::LEVEL_HEVC_HIGH_6_2, HEVCHighTierLevel62 },
-
- // map high tier levels below 4 to main tier
- { C2Config::LEVEL_HEVC_MAIN_1, HEVCHighTierLevel1 },
- { C2Config::LEVEL_HEVC_MAIN_2, HEVCHighTierLevel2 },
- { C2Config::LEVEL_HEVC_MAIN_2_1, HEVCHighTierLevel21 },
- { C2Config::LEVEL_HEVC_MAIN_3, HEVCHighTierLevel3 },
- { C2Config::LEVEL_HEVC_MAIN_3_1, HEVCHighTierLevel31 },
-};
-
-ALookup<C2Config::profile_t, int32_t> sHevcProfiles = {
- { C2Config::PROFILE_HEVC_MAIN, HEVCProfileMain },
- { C2Config::PROFILE_HEVC_MAIN_10, HEVCProfileMain10 },
- { C2Config::PROFILE_HEVC_MAIN_STILL, HEVCProfileMainStill },
- { C2Config::PROFILE_HEVC_MAIN_INTRA, HEVCProfileMain },
- { C2Config::PROFILE_HEVC_MAIN_10_INTRA, HEVCProfileMain10 },
-};
-
-ALookup<C2Config::level_t, int32_t> sMpeg2Levels = {
- { C2Config::LEVEL_MP2V_LOW, MPEG2LevelLL },
- { C2Config::LEVEL_MP2V_MAIN, MPEG2LevelML },
- { C2Config::LEVEL_MP2V_HIGH_1440, MPEG2LevelH14 },
- { C2Config::LEVEL_MP2V_HIGH, MPEG2LevelHL },
- { C2Config::LEVEL_MP2V_HIGHP, MPEG2LevelHP },
-};
-
-ALookup<C2Config::profile_t, int32_t> sMpeg2Profiles = {
- { C2Config::PROFILE_MP2V_SIMPLE, MPEG2ProfileSimple },
- { C2Config::PROFILE_MP2V_MAIN, MPEG2ProfileMain },
- { C2Config::PROFILE_MP2V_SNR_SCALABLE, MPEG2ProfileSNR },
- { C2Config::PROFILE_MP2V_SPATIALLY_SCALABLE, MPEG2ProfileSpatial },
- { C2Config::PROFILE_MP2V_HIGH, MPEG2ProfileHigh },
- { C2Config::PROFILE_MP2V_422, MPEG2Profile422 },
-};
-
-ALookup<C2Config::level_t, int32_t> sMpeg4Levels = {
- { C2Config::LEVEL_MP4V_0, MPEG4Level0 },
- { C2Config::LEVEL_MP4V_0B, MPEG4Level0b },
- { C2Config::LEVEL_MP4V_1, MPEG4Level1 },
- { C2Config::LEVEL_MP4V_2, MPEG4Level2 },
- { C2Config::LEVEL_MP4V_3, MPEG4Level3 },
- { C2Config::LEVEL_MP4V_3B, MPEG4Level3b },
- { C2Config::LEVEL_MP4V_4, MPEG4Level4 },
- { C2Config::LEVEL_MP4V_4A, MPEG4Level4a },
- { C2Config::LEVEL_MP4V_5, MPEG4Level5 },
- { C2Config::LEVEL_MP4V_6, MPEG4Level6 },
-};
-
-ALookup<C2Config::profile_t, int32_t> sMpeg4Profiles = {
- { C2Config::PROFILE_MP4V_SIMPLE, MPEG4ProfileSimple },
- { C2Config::PROFILE_MP4V_SIMPLE_SCALABLE, MPEG4ProfileSimpleScalable },
- { C2Config::PROFILE_MP4V_CORE, MPEG4ProfileCore },
- { C2Config::PROFILE_MP4V_MAIN, MPEG4ProfileMain },
- { C2Config::PROFILE_MP4V_NBIT, MPEG4ProfileNbit },
- { C2Config::PROFILE_MP4V_ARTS, MPEG4ProfileAdvancedRealTime },
- { C2Config::PROFILE_MP4V_CORE_SCALABLE, MPEG4ProfileCoreScalable },
- { C2Config::PROFILE_MP4V_ACE, MPEG4ProfileAdvancedCoding },
- { C2Config::PROFILE_MP4V_ADVANCED_CORE, MPEG4ProfileAdvancedCore },
- { C2Config::PROFILE_MP4V_ADVANCED_SIMPLE, MPEG4ProfileAdvancedSimple },
-};
-
-ALookup<C2Config::pcm_encoding_t, int32_t> sPcmEncodings = {
- { C2Config::PCM_8, kAudioEncodingPcm8bit },
- { C2Config::PCM_16, kAudioEncodingPcm16bit },
- { C2Config::PCM_FLOAT, kAudioEncodingPcmFloat },
-};
-
-ALookup<C2Config::level_t, int32_t> sVp9Levels = {
- { C2Config::LEVEL_VP9_1, VP9Level1 },
- { C2Config::LEVEL_VP9_1_1, VP9Level11 },
- { C2Config::LEVEL_VP9_2, VP9Level2 },
- { C2Config::LEVEL_VP9_2_1, VP9Level21 },
- { C2Config::LEVEL_VP9_3, VP9Level3 },
- { C2Config::LEVEL_VP9_3_1, VP9Level31 },
- { C2Config::LEVEL_VP9_4, VP9Level4 },
- { C2Config::LEVEL_VP9_4_1, VP9Level41 },
- { C2Config::LEVEL_VP9_5, VP9Level5 },
- { C2Config::LEVEL_VP9_5_1, VP9Level51 },
- { C2Config::LEVEL_VP9_5_2, VP9Level52 },
- { C2Config::LEVEL_VP9_6, VP9Level6 },
- { C2Config::LEVEL_VP9_6_1, VP9Level61 },
- { C2Config::LEVEL_VP9_6_2, VP9Level62 },
-};
-
-ALookup<C2Config::profile_t, int32_t> sVp9Profiles = {
- { C2Config::PROFILE_VP9_0, VP9Profile0 },
- { C2Config::PROFILE_VP9_1, VP9Profile1 },
- { C2Config::PROFILE_VP9_2, VP9Profile2 },
- { C2Config::PROFILE_VP9_3, VP9Profile3 },
-};
-
-/**
- * A helper that passes through vendor extension profile and level values.
- */
-struct ProfileLevelMapperHelper : C2Mapper::ProfileLevelMapper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) = 0;
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) = 0;
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) = 0;
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) = 0;
-
- template<typename T, typename U>
- bool passThroughMap(T from, U *to) {
- // allow (and pass through) vendor extensions
- if (from >= (T)C2_PROFILE_LEVEL_VENDOR_START && from < (T)INT32_MAX) {
- *to = (U)from;
- return true;
- }
- return simpleMap(from, to);
- }
-
- virtual bool mapLevel(C2Config::level_t from, int32_t *to) {
- return passThroughMap(from, to);
- }
-
- virtual bool mapLevel(int32_t from, C2Config::level_t *to) {
- return passThroughMap(from, to);
- }
-
- virtual bool mapProfile(C2Config::profile_t from, int32_t *to) {
- return passThroughMap(from, to);
- }
-
- virtual bool mapProfile(int32_t from, C2Config::profile_t *to) {
- return passThroughMap(from, to);
- }
-};
-
-// AAC only uses profiles, map all levels to unused or 0
-struct AacProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t, int32_t *to) {
- *to = 0;
- return true;
- }
- virtual bool simpleMap(int32_t, C2Config::level_t *to) {
- *to = C2Config::LEVEL_UNUSED;
- return true;
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sAacProfiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sAacProfiles.map(from, to);
- }
-};
-
-struct AvcProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sAvcLevels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sAvcLevels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sAvcProfiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sAvcProfiles.map(from, to);
- }
-};
-
-struct DolbyVisionProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sDolbyVisionLevels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sDolbyVisionLevels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sDolbyVisionProfiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sDolbyVisionProfiles.map(from, to);
- }
-};
-
-struct H263ProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sH263Levels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sH263Levels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sH263Profiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sH263Profiles.map(from, to);
- }
-};
-
-struct HevcProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sHevcLevels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sHevcLevels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sHevcProfiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sHevcProfiles.map(from, to);
- }
-};
-
-struct Mpeg2ProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sMpeg2Levels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sMpeg2Levels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sMpeg2Profiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sMpeg2Profiles.map(from, to);
- }
-};
-
-struct Mpeg4ProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sMpeg4Levels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sMpeg4Levels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sMpeg4Profiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sMpeg4Profiles.map(from, to);
- }
-};
-
-// VP8 has no profiles and levels in Codec 2.0, but we use main profile and level 0 in MediaCodec
-// map all profiles and levels to that.
-struct Vp8ProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t, int32_t *to) {
- *to = VP8Level_Version0;
- return true;
- }
- virtual bool simpleMap(int32_t, C2Config::level_t *to) {
- *to = C2Config::LEVEL_UNUSED;
- return true;
- }
- virtual bool simpleMap(C2Config::profile_t, int32_t *to) {
- *to = VP8ProfileMain;
- return true;
- }
- virtual bool simpleMap(int32_t, C2Config::profile_t *to) {
- *to = C2Config::PROFILE_UNUSED;
- return true;
- }
-};
-
-struct Vp9ProfileLevelMapper : ProfileLevelMapperHelper {
- virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
- return sVp9Levels.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::level_t *to) {
- return sVp9Levels.map(from, to);
- }
- virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
- return sVp9Profiles.map(from, to);
- }
- virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
- return sVp9Profiles.map(from, to);
- }
-};
-
-} // namespace
-
-// static
-std::shared_ptr<C2Mapper::ProfileLevelMapper>
-C2Mapper::GetProfileLevelMapper(std::string mediaType) {
- std::transform(mediaType.begin(), mediaType.begin(), mediaType.end(), ::tolower);
- if (mediaType == MIMETYPE_AUDIO_AAC) {
- return std::make_shared<AacProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_AVC) {
- return std::make_shared<AvcProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_DOLBY_VISION) {
- return std::make_shared<DolbyVisionProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_H263) {
- return std::make_shared<H263ProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_HEVC) {
- return std::make_shared<HevcProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_MPEG2) {
- return std::make_shared<Mpeg2ProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_MPEG4) {
- return std::make_shared<Mpeg4ProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_VP8) {
- return std::make_shared<Vp8ProfileLevelMapper>();
- } else if (mediaType == MIMETYPE_VIDEO_VP9) {
- return std::make_shared<Vp9ProfileLevelMapper>();
- }
- return nullptr;
-}
-
-// static
-bool C2Mapper::map(C2Config::bitrate_mode_t from, int32_t *to) {
- return sBitrateModes.map(from, to);
-}
-
-// static
-bool C2Mapper::map(int32_t from, C2Config::bitrate_mode_t *to) {
- return sBitrateModes.map(from, to);
-}
-
-// static
-bool C2Mapper::map(C2Config::pcm_encoding_t from, int32_t *to) {
- return sPcmEncodings.map(from, to);
-}
-
-// static
-bool C2Mapper::map(int32_t from, C2Config::pcm_encoding_t *to) {
- return sPcmEncodings.map(from, to);
-}
-
-// static
-bool C2Mapper::map(C2Color::range_t from, int32_t *to) {
- bool res = true;
- // map SDK defined values directly. For other values, use wrapping from ColorUtils.
- if (!sColorRanges.map(from, to)) {
- ColorAspects::Range sfRange;
-
- // map known constants and keep vendor extensions. all other values are mapped to 'Other'
- if (!sColorRangesSf.map(from, &sfRange)) {
- // use static cast and ensure it is in the extension range
- if (from < C2Color::RANGE_VENDOR_START || from > C2Color::RANGE_OTHER) {
- sfRange = ColorAspects::RangeOther;
- res = false;
- }
- }
-
- *to = ColorUtils::wrapColorAspectsIntoColorRange(sfRange);
- }
- return res;
-}
-
-// static
-bool C2Mapper::map(int32_t from, C2Color::range_t *to) {
- // map SDK defined values directly. For other values, use wrapping from ColorUtils.
- if (!sColorRanges.map(from, to)) {
- ColorAspects::Range sfRange;
- (void)ColorUtils::unwrapColorAspectsFromColorRange(from, &sfRange);
-
- // map known constants and keep vendor extensions. all other values are mapped to 'Other'
- if (!sColorRangesSf.map(sfRange, to)) {
- // use static cast and ensure it is in the extension range
- *to = (C2Color::range_t)sfRange;
- if (*to < C2Color::RANGE_VENDOR_START || *to > C2Color::RANGE_OTHER) {
- *to = C2Color::RANGE_OTHER;
- return false;
- }
- }
- }
-
- return true;
-}
-
-// static
-bool C2Mapper::map(C2Color::range_t from, ColorAspects::Range *to) {
- return sColorRangesSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(ColorAspects::Range from, C2Color::range_t *to) {
- return sColorRangesSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(C2Color::primaries_t primaries, C2Color::matrix_t matrix, int32_t *standard) {
- ColorAspects::Primaries sfPrimaries;
- ColorAspects::MatrixCoeffs sfMatrix;
- bool res = true;
-
- // map known constants and keep vendor extensions. all other values are mapped to 'Other'
- if (!sColorPrimariesSf.map(primaries, &sfPrimaries)) {
- // ensure it is in the extension range and use static cast
- if (primaries < C2Color::PRIMARIES_VENDOR_START || primaries > C2Color::PRIMARIES_OTHER) {
- // undefined non-extension values map to 'Other'
- sfPrimaries = ColorAspects::PrimariesOther;
- res = false;
- } else {
- sfPrimaries = (ColorAspects::Primaries)primaries;
- }
- }
-
- if (!sColorMatricesSf.map(matrix, &sfMatrix)) {
- // use static cast and ensure it is in the extension range
- if (matrix < C2Color::MATRIX_VENDOR_START || matrix > C2Color::MATRIX_OTHER) {
- // undefined non-extension values map to 'Other'
- sfMatrix = ColorAspects::MatrixOther;
- res = false;
- } else {
- sfMatrix = (ColorAspects::MatrixCoeffs)matrix;
- }
- }
-
- *standard = ColorUtils::wrapColorAspectsIntoColorStandard(sfPrimaries, sfMatrix);
-
- return res;
-}
-
-// static
-bool C2Mapper::map(int32_t standard, C2Color::primaries_t *primaries, C2Color::matrix_t *matrix) {
- // first map to stagefright foundation aspects => these actually map nearly 1:1 to
- // Codec 2.0 aspects
- ColorAspects::Primaries sfPrimaries;
- ColorAspects::MatrixCoeffs sfMatrix;
- bool res = true;
- (void)ColorUtils::unwrapColorAspectsFromColorStandard(standard, &sfPrimaries, &sfMatrix);
-
- // map known constants and keep vendor extensions. all other values are mapped to 'Other'
- if (!sColorPrimariesSf.map(sfPrimaries, primaries)) {
- // use static cast and ensure it is in the extension range
- *primaries = (C2Color::primaries_t)sfPrimaries;
- if (*primaries < C2Color::PRIMARIES_VENDOR_START || *primaries > C2Color::PRIMARIES_OTHER) {
- *primaries = C2Color::PRIMARIES_OTHER;
- res = false;
- }
- }
-
- if (!sColorMatricesSf.map(sfMatrix, matrix)) {
- // use static cast and ensure it is in the extension range
- *matrix = (C2Color::matrix_t)sfMatrix;
- if (*matrix < C2Color::MATRIX_VENDOR_START || *matrix > C2Color::MATRIX_OTHER) {
- *matrix = C2Color::MATRIX_OTHER;
- res = false;
- }
- }
-
- return res;
-}
-
-// static
-bool C2Mapper::map(C2Color::primaries_t from, ColorAspects::Primaries *to) {
- return sColorPrimariesSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(ColorAspects::Primaries from, C2Color::primaries_t *to) {
- return sColorPrimariesSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(C2Color::matrix_t from, ColorAspects::MatrixCoeffs *to) {
- return sColorMatricesSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(ColorAspects::MatrixCoeffs from, C2Color::matrix_t *to) {
- return sColorMatricesSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(C2Color::transfer_t from, int32_t *to) {
- bool res = true;
- // map SDK defined values directly. For other values, use wrapping from ColorUtils.
- if (!sColorTransfers.map(from, to)) {
- ColorAspects::Transfer sfTransfer;
-
- // map known constants and keep vendor extensions. all other values are mapped to 'Other'
- if (!sColorTransfersSf.map(from, &sfTransfer)) {
- // use static cast and ensure it is in the extension range
- if (from < C2Color::TRANSFER_VENDOR_START || from > C2Color::TRANSFER_OTHER) {
- sfTransfer = ColorAspects::TransferOther;
- res = false;
- }
- }
-
- *to = ColorUtils::wrapColorAspectsIntoColorTransfer(sfTransfer);
- }
- return res;
-}
-
-// static
-bool C2Mapper::map(int32_t from, C2Color::transfer_t *to) {
- // map SDK defined values directly. For other values, use wrapping from ColorUtils.
- if (!sColorTransfers.map(from, to)) {
- ColorAspects::Transfer sfTransfer;
- (void)ColorUtils::unwrapColorAspectsFromColorTransfer(from, &sfTransfer);
-
- // map known constants and keep vendor extensions. all other values are mapped to 'Other'
- if (!sColorTransfersSf.map(sfTransfer, to)) {
- // use static cast and ensure it is in the extension range
- *to = (C2Color::transfer_t)sfTransfer;
- if (*to < C2Color::TRANSFER_VENDOR_START || *to > C2Color::TRANSFER_OTHER) {
- *to = C2Color::TRANSFER_OTHER;
- return false;
- }
- }
- }
-
- return true;
-}
-
-// static
-bool C2Mapper::map(
- C2Color::range_t range, C2Color::primaries_t primaries,
- C2Color::matrix_t matrix, C2Color::transfer_t transfer, uint32_t *dataSpace) {
-#if 0
- // pure reimplementation
- *dataSpace = HAL_DATASPACE_UNKNOWN; // this is 0
-
- switch (range) {
- case C2Color::RANGE_FULL: *dataSpace |= HAL_DATASPACE_RANGE_FULL; break;
- case C2Color::RANGE_LIMITED: *dataSpace |= HAL_DATASPACE_RANGE_LIMITED; break;
- default: break;
- }
-
- switch (transfer) {
- case C2Color::TRANSFER_LINEAR: *dataSpace |= HAL_DATASPACE_TRANSFER_LINEAR; break;
- case C2Color::TRANSFER_SRGB: *dataSpace |= HAL_DATASPACE_TRANSFER_SRGB; break;
- case C2Color::TRANSFER_170M: *dataSpace |= HAL_DATASPACE_TRANSFER_SMPTE_170M; break;
- case C2Color::TRANSFER_GAMMA22: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_2; break;
- case C2Color::TRANSFER_GAMMA28: *dataSpace |= HAL_DATASPACE_TRANSFER_GAMMA2_8; break;
- case C2Color::TRANSFER_ST2084: *dataSpace |= HAL_DATASPACE_TRANSFER_ST2084; break;
- case C2Color::TRANSFER_HLG: *dataSpace |= HAL_DATASPACE_TRANSFER_HLG; break;
- default: break;
- }
-
- switch (primaries) {
- case C2Color::PRIMARIES_BT601_525:
- *dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M
- || matrix == C2Color::MATRIX_BT709)
- ? HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED
- : HAL_DATASPACE_STANDARD_BT601_525;
- break;
- case C2Color::PRIMARIES_BT601_625:
- *dataSpace |= (matrix == C2Color::MATRIX_SMPTE240M
- || matrix == C2Color::MATRIX_BT709)
- ? HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED
- : HAL_DATASPACE_STANDARD_BT601_625;
- break;
- case C2Color::PRIMARIES_BT2020:
- *dataSpace |= (matrix == C2Color::MATRIX_BT2020CONSTANT
- ? HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE
- : HAL_DATASPACE_STANDARD_BT2020);
- break;
- case C2Color::PRIMARIES_BT470_M:
- *dataSpace |= HAL_DATASPACE_STANDARD_BT470M;
- break;
- case C2Color::PRIMARIES_BT709:
- *dataSpace |= HAL_DATASPACE_STANDARD_BT709;
- break;
- default: break;
- }
-#else
- // for now use legacy implementation
- ColorAspects aspects;
- if (!sColorRangesSf.map(range, &aspects.mRange)) {
- aspects.mRange = ColorAspects::RangeUnspecified;
- }
- if (!sColorPrimariesSf.map(primaries, &aspects.mPrimaries)) {
- aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
- }
- if (!sColorMatricesSf.map(matrix, &aspects.mMatrixCoeffs)) {
- aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
- }
- if (!sColorTransfersSf.map(transfer, &aspects.mTransfer)) {
- aspects.mTransfer = ColorAspects::TransferUnspecified;
- }
- *dataSpace = ColorUtils::getDataSpaceForColorAspects(aspects, true /* mayExpand */);
-#endif
- return true;
-}
-
-// static
-bool C2Mapper::map(C2Color::transfer_t from, ColorAspects::Transfer *to) {
- return sColorTransfersSf.map(from, to);
-}
-
-// static
-bool C2Mapper::map(ColorAspects::Transfer from, C2Color::transfer_t *to) {
- return sColorTransfersSf.map(from, to);
-}
diff --git a/media/sfplugin/utils/Codec2Mapper.h b/media/sfplugin/utils/Codec2Mapper.h
deleted file mode 100644
index 1eeb92e..0000000
--- a/media/sfplugin/utils/Codec2Mapper.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_CODEC2_MAPPER_H_
-#define ANDROID_CODEC2_MAPPER_H_
-
-#include <C2Config.h>
-
-#include <media/stagefright/foundation/ColorUtils.h>
-
-#include <memory>
-
-namespace android {
-
- /**
- * Utility class to map Codec 2.0 values to android values.
- */
- struct C2Mapper {
- struct ProfileLevelMapper {
- virtual bool mapProfile(C2Config::profile_t, int32_t*) = 0;
- virtual bool mapProfile(int32_t, C2Config::profile_t*) = 0;
- virtual bool mapLevel(C2Config::level_t, int32_t*) = 0;
- virtual bool mapLevel(int32_t, C2Config::level_t*) = 0;
- virtual ~ProfileLevelMapper() = default;
- };
-
- static std::shared_ptr<ProfileLevelMapper>
- GetProfileLevelMapper(std::string mediaType);
-
- // convert between bitrates
- static bool map(C2Config::bitrate_mode_t, int32_t*);
- static bool map(int32_t, C2Config::bitrate_mode_t*);
-
- // convert between pcm encodings
- static bool map(C2Config::pcm_encoding_t, int32_t*);
- static bool map(int32_t, C2Config::pcm_encoding_t*);
-
- // convert between picture types
- static bool map(C2Config::picture_type_t, int32_t*);
- static bool map(int32_t, C2Config::picture_type_t*);
-
- // convert between color aspects
- static bool map(C2Color::range_t, int32_t*);
- static bool map(int32_t, C2Color::range_t*);
- static bool map(C2Color::primaries_t, C2Color::matrix_t, int32_t*);
- static bool map(int32_t, C2Color::primaries_t*, C2Color::matrix_t*);
- static bool map(C2Color::transfer_t, int32_t*);
- static bool map(int32_t, C2Color::transfer_t*);
-
- static bool map(
- C2Color::range_t, C2Color::primaries_t, C2Color::matrix_t, C2Color::transfer_t,
- uint32_t *dataSpace);
-
- static bool map(C2Color::range_t, ColorAspects::Range*);
- static bool map(ColorAspects::Range, C2Color::range_t*);
- static bool map(C2Color::primaries_t, ColorAspects::Primaries*);
- static bool map(ColorAspects::Primaries, C2Color::primaries_t*);
- static bool map(C2Color::matrix_t, ColorAspects::MatrixCoeffs*);
- static bool map(ColorAspects::MatrixCoeffs, C2Color::matrix_t*);
- static bool map(C2Color::transfer_t, ColorAspects::Transfer*);
- static bool map(ColorAspects::Transfer, C2Color::transfer_t*);
- };
-}
-
-#endif // ANDROID_CODEC2_MAPPER_H_