1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// #define LOG_NDEBUG 0
18#define LOG_TAG "SoftVP9Encoder"
19#include "SoftVP9Encoder.h"
20
21#include <utils/Log.h>
22#include <utils/misc.h>
23
24#include <media/hardware/HardwareAPI.h>
25#include <media/hardware/MetadataBufferType.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/MediaDefs.h>
28
29namespace android {
30
31static const CodecProfileLevel kVp9ProfileLevels[] = {
32    { OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level41 },
33};
34
35SoftVP9Encoder::SoftVP9Encoder(
36        const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
37        OMX_COMPONENTTYPE **component)
38    : SoftVPXEncoder(
39            name, callbacks, appData, component, "video_encoder.vp9",
40            OMX_VIDEO_CodingVP9, MEDIA_MIMETYPE_VIDEO_VP9, 4,
41            kVp9ProfileLevels, NELEM(kVp9ProfileLevels)),
42      mLevel(OMX_VIDEO_VP9Level1),
43      mTileColumns(0),
44      mFrameParallelDecoding(OMX_FALSE) {
45}
46
47void SoftVP9Encoder::setCodecSpecificInterface() {
48    mCodecInterface = vpx_codec_vp9_cx();
49}
50
51void SoftVP9Encoder::setCodecSpecificConfiguration() {
52    mCodecConfiguration->g_profile = 0;
53}
54
55vpx_codec_err_t SoftVP9Encoder::setCodecSpecificControls() {
56    vpx_codec_err_t codecReturn = vpx_codec_control(
57            mCodecContext, VP9E_SET_TILE_COLUMNS, mTileColumns);
58    if (codecReturn != VPX_CODEC_OK) {
59        ALOGE("Error setting VP9E_SET_TILE_COLUMNS to %d. vpx_codec_control() "
60              "returned %d", mTileColumns, codecReturn);
61        return codecReturn;
62    }
63    codecReturn = vpx_codec_control(
64            mCodecContext, VP9E_SET_FRAME_PARALLEL_DECODING,
65            mFrameParallelDecoding);
66    if (codecReturn != VPX_CODEC_OK) {
67        ALOGE("Error setting VP9E_SET_FRAME_PARALLEL_DECODING to %d."
68              "vpx_codec_control() returned %d", mFrameParallelDecoding,
69              codecReturn);
70        return codecReturn;
71    }
72    codecReturn = vpx_codec_control(mCodecContext, VP9E_SET_ROW_MT, 1);
73    if (codecReturn != VPX_CODEC_OK) {
74        ALOGE("Error setting VP9E_SET_ROW_MT to 1. vpx_codec_control() "
75              "returned %d", codecReturn);
76        return codecReturn;
77    }
78
79    // For VP9, we always set CPU_USED to 8 (because the realtime default is 0
80    // which is too slow).
81    codecReturn = vpx_codec_control(mCodecContext, VP8E_SET_CPUUSED, 8);
82    if (codecReturn != VPX_CODEC_OK) {
83        ALOGE("Error setting VP8E_SET_CPUUSED to 8. vpx_codec_control() "
84              "returned %d", codecReturn);
85        return codecReturn;
86    }
87    return codecReturn;
88}
89
90OMX_ERRORTYPE SoftVP9Encoder::internalGetParameter(
91        OMX_INDEXTYPE index, OMX_PTR param) {
92    // can include extension index OMX_INDEXEXTTYPE
93    const int32_t indexFull = index;
94
95    switch (indexFull) {
96        case OMX_IndexParamVideoVp9:
97            return internalGetVp9Params(
98                    (OMX_VIDEO_PARAM_VP9TYPE *)param);
99
100        default:
101            return SoftVPXEncoder::internalGetParameter(index, param);
102    }
103}
104
105OMX_ERRORTYPE SoftVP9Encoder::internalSetParameter(
106        OMX_INDEXTYPE index, const OMX_PTR param) {
107    // can include extension index OMX_INDEXEXTTYPE
108    const int32_t indexFull = index;
109
110    switch (indexFull) {
111        case OMX_IndexParamVideoVp9:
112            return internalSetVp9Params(
113                    (const OMX_VIDEO_PARAM_VP9TYPE *)param);
114
115        default:
116            return SoftVPXEncoder::internalSetParameter(index, param);
117    }
118}
119
120OMX_ERRORTYPE SoftVP9Encoder::internalGetVp9Params(
121        OMX_VIDEO_PARAM_VP9TYPE *vp9Params) {
122    if (vp9Params->nPortIndex != kOutputPortIndex) {
123        return OMX_ErrorUnsupportedIndex;
124    }
125
126    vp9Params->eProfile = OMX_VIDEO_VP9Profile0;
127    vp9Params->eLevel = mLevel;
128    vp9Params->bErrorResilientMode = mErrorResilience;
129    vp9Params->nTileColumns = mTileColumns;
130    vp9Params->bEnableFrameParallelDecoding = mFrameParallelDecoding;
131    return OMX_ErrorNone;
132}
133
134OMX_ERRORTYPE SoftVP9Encoder::internalSetVp9Params(
135        const OMX_VIDEO_PARAM_VP9TYPE *vp9Params) {
136    if (vp9Params->nPortIndex != kOutputPortIndex) {
137        return OMX_ErrorUnsupportedIndex;
138    }
139
140    if (vp9Params->eProfile != OMX_VIDEO_VP9Profile0) {
141        return OMX_ErrorBadParameter;
142    }
143
144    if (vp9Params->eLevel == OMX_VIDEO_VP9Level1 ||
145        vp9Params->eLevel == OMX_VIDEO_VP9Level11 ||
146        vp9Params->eLevel == OMX_VIDEO_VP9Level2 ||
147        vp9Params->eLevel == OMX_VIDEO_VP9Level21 ||
148        vp9Params->eLevel == OMX_VIDEO_VP9Level3 ||
149        vp9Params->eLevel == OMX_VIDEO_VP9Level31 ||
150        vp9Params->eLevel == OMX_VIDEO_VP9Level4 ||
151        vp9Params->eLevel == OMX_VIDEO_VP9Level41 ||
152        vp9Params->eLevel == OMX_VIDEO_VP9Level5 ||
153        vp9Params->eLevel == OMX_VIDEO_VP9Level51 ||
154        vp9Params->eLevel == OMX_VIDEO_VP9Level52 ||
155        vp9Params->eLevel == OMX_VIDEO_VP9Level6 ||
156        vp9Params->eLevel == OMX_VIDEO_VP9Level61 ||
157        vp9Params->eLevel == OMX_VIDEO_VP9Level62) {
158        mLevel = vp9Params->eLevel;
159    } else {
160        return OMX_ErrorBadParameter;
161    }
162
163    mErrorResilience = vp9Params->bErrorResilientMode;
164    mTileColumns = vp9Params->nTileColumns;
165    mFrameParallelDecoding = vp9Params->bEnableFrameParallelDecoding;
166    return OMX_ErrorNone;
167}
168
169}  // namespace android
170