blob: 04737a9ccf5c170a97778d46a6b89db4adb4bd69 [file] [log] [blame]
/*
* Copyright (C) 2016 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 "SoftVP8Encoder"
#include "SoftVP8Encoder.h"
#include <utils/Log.h>
#include <utils/misc.h>
#include <media/hardware/HardwareAPI.h>
#include <media/hardware/MetadataBufferType.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#ifndef INT32_MAX
#define INT32_MAX 2147483647
#endif
namespace android {
static const CodecProfileLevel kVp8ProfileLevels[] = {
{ OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version0 },
{ OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version1 },
{ OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version2 },
{ OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version3 },
};
SoftVP8Encoder::SoftVP8Encoder(const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component)
: SoftVPXEncoder(
name, callbacks, appData, component, "video_encoder.vp8",
OMX_VIDEO_CodingVP8, MEDIA_MIMETYPE_VIDEO_VP8, 2,
kVp8ProfileLevels, NELEM(kVp8ProfileLevels)),
mDCTPartitions(0),
mLevel(OMX_VIDEO_VP8Level_Version0) {
}
void SoftVP8Encoder::setCodecSpecificInterface() {
mCodecInterface = vpx_codec_vp8_cx();
}
void SoftVP8Encoder::setCodecSpecificConfiguration() {
switch (mLevel) {
case OMX_VIDEO_VP8Level_Version0:
mCodecConfiguration->g_profile = 0;
break;
case OMX_VIDEO_VP8Level_Version1:
mCodecConfiguration->g_profile = 1;
break;
case OMX_VIDEO_VP8Level_Version2:
mCodecConfiguration->g_profile = 2;
break;
case OMX_VIDEO_VP8Level_Version3:
mCodecConfiguration->g_profile = 3;
break;
default:
mCodecConfiguration->g_profile = 0;
}
}
vpx_codec_err_t SoftVP8Encoder::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;
}
OMX_ERRORTYPE SoftVP8Encoder::internalGetParameter(OMX_INDEXTYPE index,
OMX_PTR param) {
// can include extension index OMX_INDEXEXTTYPE
const int32_t indexFull = index;
switch (indexFull) {
case OMX_IndexParamVideoVp8:
return internalGetVp8Params(
(OMX_VIDEO_PARAM_VP8TYPE *)param);
default:
return SoftVPXEncoder::internalGetParameter(index, param);
}
}
OMX_ERRORTYPE SoftVP8Encoder::internalSetParameter(OMX_INDEXTYPE index,
const OMX_PTR param) {
// can include extension index OMX_INDEXEXTTYPE
const int32_t indexFull = index;
switch (indexFull) {
case OMX_IndexParamVideoVp8:
return internalSetVp8Params(
(const OMX_VIDEO_PARAM_VP8TYPE *)param);
default:
return SoftVPXEncoder::internalSetParameter(index, param);
}
}
OMX_ERRORTYPE SoftVP8Encoder::internalGetVp8Params(
OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
if (vp8Params->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
vp8Params->eProfile = OMX_VIDEO_VP8ProfileMain;
vp8Params->eLevel = mLevel;
vp8Params->bErrorResilientMode = mErrorResilience;
vp8Params->nDCTPartitions = mDCTPartitions;
return OMX_ErrorNone;
}
OMX_ERRORTYPE SoftVP8Encoder::internalSetVp8Params(
const OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
if (vp8Params->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
if (vp8Params->eProfile != OMX_VIDEO_VP8ProfileMain) {
return OMX_ErrorBadParameter;
}
if (vp8Params->eLevel == OMX_VIDEO_VP8Level_Version0 ||
vp8Params->eLevel == OMX_VIDEO_VP8Level_Version1 ||
vp8Params->eLevel == OMX_VIDEO_VP8Level_Version2 ||
vp8Params->eLevel == OMX_VIDEO_VP8Level_Version3) {
mLevel = vp8Params->eLevel;
} else {
return OMX_ErrorBadParameter;
}
mErrorResilience = vp8Params->bErrorResilientMode;
if (vp8Params->nDCTPartitions <= kMaxDCTPartitions) {
mDCTPartitions = vp8Params->nDCTPartitions;
} else {
return OMX_ErrorBadParameter;
}
return OMX_ErrorNone;
}
} // namespace android