1b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin/*
2b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * Copyright (C) 2013 The Android Open Source Project
3b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin *
4b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * Licensed under the Apache License, Version 2.0 (the "License");
5b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * you may not use this file except in compliance with the License.
6b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * You may obtain a copy of the License at
7b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin *
8b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin *      http://www.apache.org/licenses/LICENSE-2.0
9b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin *
10b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * Unless required by applicable law or agreed to in writing, software
11b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * distributed under the License is distributed on an "AS IS" BASIS,
12b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * See the License for the specific language governing permissions and
14b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin * limitations under the License.
15b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin */
16b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
17b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin// #define LOG_NDEBUG 0
18b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#define LOG_TAG "SoftVPXEncoder"
19b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#include "SoftVPXEncoder.h"
20b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
21b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#include <utils/Log.h>
22a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar#include <utils/misc.h>
23b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
24a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber#include <media/hardware/HardwareAPI.h>
25a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber#include <media/hardware/MetadataBufferType.h>
26b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#include <media/stagefright/foundation/ADebug.h>
27b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#include <media/stagefright/MediaDefs.h>
28b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
2987f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#ifndef INT32_MAX
3087f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#define INT32_MAX   2147483647
3187f8cbb223ee516803dbb99699320c2484cbf3baWei Jia#endif
3287f8cbb223ee516803dbb99699320c2484cbf3baWei Jia
33b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekinnamespace android {
34b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
35b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekintemplate<class T>
36b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekinstatic void InitOMXParams(T *params) {
37b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    params->nSize = sizeof(T);
38b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // OMX IL 1.1.2
39b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    params->nVersion.s.nVersionMajor = 1;
40b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    params->nVersion.s.nVersionMinor = 1;
41b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    params->nVersion.s.nRevision = 2;
42b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    params->nVersion.s.nStep = 0;
43b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
44b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
45b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
46b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekinstatic int GetCPUCoreCount() {
47b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    int cpuCoreCount = 1;
48b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#if defined(_SC_NPROCESSORS_ONLN)
49b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
50b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#else
51b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // _SC_NPROC_ONLN must be defined...
52b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
53b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin#endif
54b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    CHECK_GE(cpuCoreCount, 1);
55b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    return cpuCoreCount;
56b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
57b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
58a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarstatic const CodecProfileLevel kProfileLevels[] = {
59a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version0 },
60a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version1 },
61a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version2 },
62a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    { OMX_VIDEO_VP8ProfileMain, OMX_VIDEO_VP8Level_Version3 },
63a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar};
64a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar
65b4698f79230bbee15936641d951d49655f9e6da5Kunter GultekinSoftVPXEncoder::SoftVPXEncoder(const char *name,
66b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                               const OMX_CALLBACKTYPE *callbacks,
67b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                               OMX_PTR appData,
68b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                               OMX_COMPONENTTYPE **component)
69a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    : SoftVideoEncoderOMXComponent(
70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            name, "video_encoder.vp8", OMX_VIDEO_CodingVP8,
71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            kProfileLevels, NELEM(kProfileLevels),
72a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            176 /* width */, 144 /* height */,
73a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            callbacks, appData, component),
74b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mCodecContext(NULL),
75b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mCodecConfiguration(NULL),
76b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mCodecInterface(NULL),
7730c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann      mBitrateUpdated(false),
78b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mBitrateControlMode(VPX_VBR),  // variable bitrate
79b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mDCTPartitions(0),
80b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mErrorResilience(OMX_FALSE),
81b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin      mLevel(OMX_VIDEO_VP8Level_Version0),
824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mKeyFrameInterval(0),
834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mMinQuantizer(0),
844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mMaxQuantizer(0),
854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mTemporalLayers(0),
864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mTemporalPatternType(OMX_VIDEO_VPXTemporalLayerPatternNone),
874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mTemporalPatternLength(0),
884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mTemporalPatternIdx(0),
894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev      mLastTimestamp(0x7FFFFFFFFFFFFFFFLL),
90a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber      mConversionBuffer(NULL),
91336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber      mKeyFrameRequested(false) {
924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    memset(mTemporalLayerBitrateRatio, 0, sizeof(mTemporalLayerBitrateRatio));
934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mTemporalLayerBitrateRatio[0] = 100;
94b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
95a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    const size_t kMinOutputBufferSize = 1024 * 1024; // arbitrary
96b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
97a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    initPorts(
98a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            kNumBuffers, kNumBuffers, kMinOutputBufferSize,
99a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            MEDIA_MIMETYPE_VIDEO_VP8, 2 /* minCompressionRatio */);
100b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
101b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
102b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
103a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos MolnarSoftVPXEncoder::~SoftVPXEncoder() {
104a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    releaseEncoder();
105b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
106b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
107b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekinstatus_t SoftVPXEncoder::initEncoder() {
108b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    vpx_codec_err_t codec_return;
109e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia    status_t result = UNKNOWN_ERROR;
110b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
111b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecInterface = vpx_codec_vp8_cx();
112b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (mCodecInterface == NULL) {
113e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia        goto CLEAN_UP;
114b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
1154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    ALOGD("VP8: initEncoder. BRMode: %u. TSLayers: %zu. KF: %u. QP: %u - %u",
1164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev          (uint32_t)mBitrateControlMode, mTemporalLayers, mKeyFrameInterval,
1174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev          mMinQuantizer, mMaxQuantizer);
118e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia
119e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia    mCodecConfiguration = new vpx_codec_enc_cfg_t;
120b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    codec_return = vpx_codec_enc_config_default(mCodecInterface,
121b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                                mCodecConfiguration,
122b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                                0);  // Codec specific flags
123b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
124b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (codec_return != VPX_CODEC_OK) {
125b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        ALOGE("Error populating default configuration for vpx encoder.");
126e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia        goto CLEAN_UP;
127b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
128b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
129b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->g_w = mWidth;
130b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->g_h = mHeight;
131b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->g_threads = GetCPUCoreCount();
132b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->g_error_resilient = mErrorResilience;
133b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
134b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    switch (mLevel) {
135b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        case OMX_VIDEO_VP8Level_Version0:
136b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            mCodecConfiguration->g_profile = 0;
137b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            break;
138b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
139b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        case OMX_VIDEO_VP8Level_Version1:
140b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            mCodecConfiguration->g_profile = 1;
141b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            break;
142b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
143b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        case OMX_VIDEO_VP8Level_Version2:
144b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            mCodecConfiguration->g_profile = 2;
145b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            break;
146b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
147b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        case OMX_VIDEO_VP8Level_Version3:
148b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            mCodecConfiguration->g_profile = 3;
149b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            break;
150b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
151b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        default:
152b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            mCodecConfiguration->g_profile = 0;
153b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
154b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
155b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // OMX timebase unit is microsecond
156b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // g_timebase is in seconds (i.e. 1/1000000 seconds)
157b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->g_timebase.num = 1;
158b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->g_timebase.den = 1000000;
159b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // rc_target_bitrate is in kbps, mBitrate in bps
1604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mCodecConfiguration->rc_target_bitrate = (mBitrate + 500) / 1000;
161b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecConfiguration->rc_end_usage = mBitrateControlMode;
1620d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    // Disable frame drop - not allowed in MediaCodec now.
1630d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    mCodecConfiguration->rc_dropframe_thresh = 0;
1640d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    if (mBitrateControlMode == VPX_CBR) {
1650d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Disable spatial resizing.
1660d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->rc_resize_allowed = 0;
1670d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Single-pass mode.
1680d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->g_pass = VPX_RC_ONE_PASS;
1690d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Maximum amount of bits that can be subtracted from the target
1700d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // bitrate - expressed as percentage of the target bitrate.
1710d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->rc_undershoot_pct = 100;
1720d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Maximum amount of bits that can be added to the target
1730d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // bitrate - expressed as percentage of the target bitrate.
1740d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->rc_overshoot_pct = 15;
1750d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Initial value of the buffer level in ms.
1760d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->rc_buf_initial_sz = 500;
1770d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Amount of data that the encoder should try to maintain in ms.
1780d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->rc_buf_optimal_sz = 600;
1790d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // The amount of data that may be buffered by the decoding
1800d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // application in ms.
1810d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->rc_buf_sz = 1000;
1820d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Enable error resilience - needed for packet loss.
1830d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->g_error_resilient = 1;
1840d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Disable lagged encoding.
1850d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->g_lag_in_frames = 0;
1864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        // Maximum key frame interval - for CBR boost to 3000
1874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->kf_max_dist = 3000;
1880d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        // Encoder determines optimal key frame placement automatically.
1890d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        mCodecConfiguration->kf_mode = VPX_KF_AUTO;
1900d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    }
191b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
1924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    // Frames temporal pattern - for now WebRTC like pattern is only supported.
1934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    switch (mTemporalLayers) {
1944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case 0:
1954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {
1964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPatternLength = 0;
1974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
1984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
1994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case 1:
2004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {
2014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_number_layers = 1;
2024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_rate_decimator[0] = 1;
2034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_periodicity = 1;
2044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[0] = 0;
2054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[0] = kTemporalUpdateLastRefAll;
2064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPatternLength = 1;
2074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
2084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
2094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case 2:
2104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {
2114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_number_layers = 2;
2124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_rate_decimator[0] = 2;
2134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_rate_decimator[1] = 1;
2144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_periodicity = 2;
2154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[0] = 0;
2164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[1] = 1;
2174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[0] = kTemporalUpdateLastAndGoldenRefAltRef;
2184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[1] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
2194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[2] = kTemporalUpdateLastRefAltRef;
2204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[3] = kTemporalUpdateGoldenRefAltRef;
2214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[4] = kTemporalUpdateLastRefAltRef;
2224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[5] = kTemporalUpdateGoldenRefAltRef;
2234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[6] = kTemporalUpdateLastRefAltRef;
2244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[7] = kTemporalUpdateNone;
2254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPatternLength = 8;
2264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
2274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
2284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case 3:
2294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {
2304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_number_layers = 3;
2314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_rate_decimator[0] = 4;
2324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_rate_decimator[1] = 2;
2334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_rate_decimator[2] = 1;
2344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_periodicity = 4;
2354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[0] = 0;
2364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[1] = 2;
2374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[2] = 1;
2384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->ts_layer_id[3] = 2;
2394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[0] = kTemporalUpdateLastAndGoldenRefAltRef;
2404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[1] = kTemporalUpdateNoneNoRefGoldenRefAltRef;
2414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[2] = kTemporalUpdateGoldenWithoutDependencyRefAltRef;
2424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[3] = kTemporalUpdateNone;
2434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[4] = kTemporalUpdateLastRefAltRef;
2444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[5] = kTemporalUpdateNone;
2454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[6] = kTemporalUpdateGoldenRefAltRef;
2464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPattern[7] = kTemporalUpdateNone;
2474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalPatternLength = 8;
2484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
2494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
2504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        default:
2514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {
252a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGE("Wrong number of temporal layers %zu", mTemporalLayers);
253e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia            goto CLEAN_UP;
2544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
2554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
2564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
2574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    // Set bitrate values for each layer
2584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    for (size_t i = 0; i < mCodecConfiguration->ts_number_layers; i++) {
2594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->ts_target_bitrate[i] =
2604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mCodecConfiguration->rc_target_bitrate *
2614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mTemporalLayerBitrateRatio[i] / 100;
2624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
2634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (mKeyFrameInterval > 0) {
2644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->kf_max_dist = mKeyFrameInterval;
2654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->kf_min_dist = mKeyFrameInterval;
2664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->kf_mode = VPX_KF_AUTO;
2674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
2684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (mMinQuantizer > 0) {
2694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->rc_min_quantizer = mMinQuantizer;
2704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
2714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (mMaxQuantizer > 0) {
2724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mCodecConfiguration->rc_max_quantizer = mMaxQuantizer;
2734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
2744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
275e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia    mCodecContext = new vpx_codec_ctx_t;
276b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    codec_return = vpx_codec_enc_init(mCodecContext,
277b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                      mCodecInterface,
278b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                      mCodecConfiguration,
279b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                      0);  // flags
280b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
281b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (codec_return != VPX_CODEC_OK) {
282b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        ALOGE("Error initializing vpx encoder");
283e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia        goto CLEAN_UP;
284b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
285b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
286b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    codec_return = vpx_codec_control(mCodecContext,
287b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                     VP8E_SET_TOKEN_PARTITIONS,
288b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                     mDCTPartitions);
289b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (codec_return != VPX_CODEC_OK) {
290b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        ALOGE("Error setting dct partitions for vpx encoder.");
291e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia        goto CLEAN_UP;
292b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
293b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
2940d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    // Extra CBR settings
2950d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    if (mBitrateControlMode == VPX_CBR) {
2960d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        codec_return = vpx_codec_control(mCodecContext,
2970d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                                         VP8E_SET_STATIC_THRESHOLD,
2980d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                                         1);
2990d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        if (codec_return == VPX_CODEC_OK) {
3000d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            uint32_t rc_max_intra_target =
3010d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                mCodecConfiguration->rc_buf_optimal_sz * (mFramerate >> 17) / 10;
3020d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            // Don't go below 3 times per frame bandwidth.
3030d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            if (rc_max_intra_target < 300) {
3040d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                rc_max_intra_target = 300;
3050d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            }
3060d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            codec_return = vpx_codec_control(mCodecContext,
3070d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                                             VP8E_SET_MAX_INTRA_BITRATE_PCT,
3080d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                                             rc_max_intra_target);
3090d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        }
3100d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        if (codec_return == VPX_CODEC_OK) {
3110d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            codec_return = vpx_codec_control(mCodecContext,
3120d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                                             VP8E_SET_CPUUSED,
3130d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                                             -8);
3140d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        }
3150d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        if (codec_return != VPX_CODEC_OK) {
3160d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev            ALOGE("Error setting cbr parameters for vpx encoder.");
317e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia            goto CLEAN_UP;
3180d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev        }
3190d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev    }
3200d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev
3212edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar    if (mColorFormat != OMX_COLOR_FormatYUV420Planar || mInputDataIsMeta) {
3222edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        free(mConversionBuffer);
32387f8cbb223ee516803dbb99699320c2484cbf3baWei Jia        mConversionBuffer = NULL;
32487f8cbb223ee516803dbb99699320c2484cbf3baWei Jia        if (((uint64_t)mWidth * mHeight) > ((uint64_t)INT32_MAX / 3)) {
325e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia            ALOGE("b/25812794, Buffer size is too big, width=%d, height=%d.", mWidth, mHeight);
326e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia            goto CLEAN_UP;
32787f8cbb223ee516803dbb99699320c2484cbf3baWei Jia        }
3282edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        mConversionBuffer = (uint8_t *)malloc(mWidth * mHeight * 3 / 2);
329b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        if (mConversionBuffer == NULL) {
3302edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            ALOGE("Allocating conversion buffer failed.");
331e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia            goto CLEAN_UP;
332b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
333b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
334b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    return OK;
335e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia
336e35ff4de22fec058d57f694e86b906ca8b8007ddWei JiaCLEAN_UP:
337e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia    releaseEncoder();
338e35ff4de22fec058d57f694e86b906ca8b8007ddWei Jia    return result;
339b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
340b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
341b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
342b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekinstatus_t SoftVPXEncoder::releaseEncoder() {
343b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (mCodecContext != NULL) {
344b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vpx_codec_destroy(mCodecContext);
345b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        delete mCodecContext;
346b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mCodecContext = NULL;
347b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
348b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
349b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (mCodecConfiguration != NULL) {
350b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        delete mCodecConfiguration;
351b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mCodecConfiguration = NULL;
352b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
353b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
354b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (mConversionBuffer != NULL) {
3552edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        free(mConversionBuffer);
356b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mConversionBuffer = NULL;
357b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
358b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
359b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // this one is not allocated by us
360b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mCodecInterface = NULL;
361b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
362b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    return OK;
363b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
364b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
365b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
366b4698f79230bbee15936641d951d49655f9e6da5Kunter GultekinOMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index,
367b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                                   OMX_PTR param) {
368b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // can include extension index OMX_INDEXEXTTYPE
369b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    const int32_t indexFull = index;
370b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
371b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    switch (indexFull) {
372b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        case OMX_IndexParamVideoBitrate: {
373b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            OMX_VIDEO_PARAM_BITRATETYPE *bitrate =
374b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                (OMX_VIDEO_PARAM_BITRATETYPE *)param;
375b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
3762720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(bitrate)) {
3772720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
3782720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
3792720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
3802720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (bitrate->nPortIndex != kOutputPortIndex) {
3812720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorUnsupportedIndex;
3822720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
3832720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
3842720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            bitrate->nTargetBitrate = mBitrate;
3852720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
3862720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (mBitrateControlMode == VPX_VBR) {
3872720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                bitrate->eControlRate = OMX_Video_ControlRateVariable;
3882720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            } else if (mBitrateControlMode == VPX_CBR) {
3892720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                bitrate->eControlRate = OMX_Video_ControlRateConstant;
3902720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            } else {
3912720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorUnsupportedSetting;
3922720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
3932720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            return OMX_ErrorNone;
394b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
395b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
396b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        // VP8 specific parameters that use extension headers
397b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        case OMX_IndexParamVideoVp8: {
398b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            OMX_VIDEO_PARAM_VP8TYPE *vp8Params =
399b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                (OMX_VIDEO_PARAM_VP8TYPE *)param;
400b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
4012720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(vp8Params)) {
4022720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
4032720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
4042720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4052720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (vp8Params->nPortIndex != kOutputPortIndex) {
4062720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorUnsupportedIndex;
4072720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
408b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
4092720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8Params->eProfile = OMX_VIDEO_VP8ProfileMain;
4102720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8Params->eLevel = mLevel;
4112720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8Params->nDCTPartitions = mDCTPartitions;
4122720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8Params->bErrorResilientMode = mErrorResilience;
4132720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            return OMX_ErrorNone;
414b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
415b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
4164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case OMX_IndexParamVideoAndroidVp8Encoder: {
4174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vp8AndroidParams =
4184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                (OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *)param;
4194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4202720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(vp8AndroidParams)) {
4212720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
4222720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
4232720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4242720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (vp8AndroidParams->nPortIndex != kOutputPortIndex) {
4252720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorUnsupportedIndex;
4262720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
4272720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8AndroidParams->nKeyFrameInterval = mKeyFrameInterval;
4292720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8AndroidParams->eTemporalPattern = mTemporalPatternType;
4302720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8AndroidParams->nTemporalLayerCount = mTemporalLayers;
4312720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8AndroidParams->nMinQuantizer = mMinQuantizer;
4322720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            vp8AndroidParams->nMaxQuantizer = mMaxQuantizer;
4332720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            memcpy(vp8AndroidParams->nTemporalLayerBitrateRatio,
4342720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                   mTemporalLayerBitrateRatio, sizeof(mTemporalLayerBitrateRatio));
4352720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            return OMX_ErrorNone;
4364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
4374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
438b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        default:
439a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SoftVideoEncoderOMXComponent::internalGetParameter(index, param);
440b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
441b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
442b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
443b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
444b4698f79230bbee15936641d951d49655f9e6da5Kunter GultekinOMX_ERRORTYPE SoftVPXEncoder::internalSetParameter(OMX_INDEXTYPE index,
445b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                                                   const OMX_PTR param) {
446b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // can include extension index OMX_INDEXEXTTYPE
447b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    const int32_t indexFull = index;
448b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
449b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    switch (indexFull) {
4502720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        case OMX_IndexParamVideoBitrate: {
4512720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            const OMX_VIDEO_PARAM_BITRATETYPE *bitRate =
4522720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                (const OMX_VIDEO_PARAM_BITRATETYPE*) param;
453b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
4542720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(bitRate)) {
4552720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
4562720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
457b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
4582720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            return internalSetBitrateParams(bitRate);
4592720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        }
4602720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4612720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        case OMX_IndexParamVideoVp8: {
4622720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            const OMX_VIDEO_PARAM_VP8TYPE *vp8Params =
4632720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                (const OMX_VIDEO_PARAM_VP8TYPE*) param;
4642720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4652720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(vp8Params)) {
4662720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
4672720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
4682720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4692720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            return internalSetVp8Params(vp8Params);
4702720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        }
4712720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4722720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        case OMX_IndexParamVideoAndroidVp8Encoder: {
4732720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vp8AndroidParams =
4742720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                (const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE*) param;
4752720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4762720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(vp8AndroidParams)) {
4772720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
4782720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
4792720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
4802720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            return internalSetAndroidVp8Params(vp8AndroidParams);
4812720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen        }
4824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
483b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        default:
484a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            return SoftVideoEncoderOMXComponent::internalSetParameter(index, param);
485b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
486b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
487b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
488336da16a12423c496efba6ca9813d5d42a1f70f6Andreas HuberOMX_ERRORTYPE SoftVPXEncoder::setConfig(
489336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        OMX_INDEXTYPE index, const OMX_PTR _params) {
490336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber    switch (index) {
491336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        case OMX_IndexConfigVideoIntraVOPRefresh:
492336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        {
493336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            OMX_CONFIG_INTRAREFRESHVOPTYPE *params =
494336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber                (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params;
495336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber
4962720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(params)) {
4972720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
4982720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
4992720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
500336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            if (params->nPortIndex != kOutputPortIndex) {
501336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber                return OMX_ErrorBadPortIndex;
502336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            }
503336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber
504336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            mKeyFrameRequested = params->IntraRefreshVOP;
505336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            return OMX_ErrorNone;
506336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        }
507336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber
50830c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann        case OMX_IndexConfigVideoBitrate:
50930c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann        {
51030c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            OMX_VIDEO_CONFIG_BITRATETYPE *params =
51130c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                (OMX_VIDEO_CONFIG_BITRATETYPE *)_params;
51230c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann
5132720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(params)) {
5142720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
5152720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
5162720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
51730c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            if (params->nPortIndex != kOutputPortIndex) {
51830c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                return OMX_ErrorBadPortIndex;
51930c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            }
52030c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann
52130c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            if (mBitrate != params->nEncodeBitrate) {
52230c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                mBitrate = params->nEncodeBitrate;
52330c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                mBitrateUpdated = true;
52430c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            }
52530c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            return OMX_ErrorNone;
52630c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann        }
52730c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann
528336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        default:
529336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            return SimpleSoftOMXComponent::setConfig(index, _params);
530336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber    }
531336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber}
532336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber
533b4698f79230bbee15936641d951d49655f9e6da5Kunter GultekinOMX_ERRORTYPE SoftVPXEncoder::internalSetVp8Params(
534b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        const OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
535b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (vp8Params->nPortIndex != kOutputPortIndex) {
536b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        return OMX_ErrorUnsupportedIndex;
537b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
538b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
539b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (vp8Params->eProfile != OMX_VIDEO_VP8ProfileMain) {
540b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        return OMX_ErrorBadParameter;
541b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
542b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
543b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (vp8Params->eLevel == OMX_VIDEO_VP8Level_Version0 ||
544b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vp8Params->eLevel == OMX_VIDEO_VP8Level_Version1 ||
545b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vp8Params->eLevel == OMX_VIDEO_VP8Level_Version2 ||
546b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vp8Params->eLevel == OMX_VIDEO_VP8Level_Version3) {
547b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mLevel = vp8Params->eLevel;
548b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    } else {
549b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        return OMX_ErrorBadParameter;
550b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
551b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
552b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (vp8Params->nDCTPartitions <= kMaxDCTPartitions) {
553b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mDCTPartitions = vp8Params->nDCTPartitions;
554b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    } else {
555b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        return OMX_ErrorBadParameter;
556b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
557b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
558b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mErrorResilience = vp8Params->bErrorResilientMode;
559b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    return OMX_ErrorNone;
560b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
561b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
5624154795d5526750b7aec5f774831a9e1ba0a3f15Alex GlaznevOMX_ERRORTYPE SoftVPXEncoder::internalSetAndroidVp8Params(
5634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE* vp8AndroidParams) {
5644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (vp8AndroidParams->nPortIndex != kOutputPortIndex) {
5654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        return OMX_ErrorUnsupportedIndex;
5664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
5674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (vp8AndroidParams->eTemporalPattern != OMX_VIDEO_VPXTemporalLayerPatternNone &&
5684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8AndroidParams->eTemporalPattern != OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
5694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        return OMX_ErrorBadParameter;
5704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
5714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (vp8AndroidParams->nTemporalLayerCount > OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
5724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        return OMX_ErrorBadParameter;
5734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
5744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (vp8AndroidParams->nMinQuantizer > vp8AndroidParams->nMaxQuantizer) {
5754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        return OMX_ErrorBadParameter;
5764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
5774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
5784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mTemporalPatternType = vp8AndroidParams->eTemporalPattern;
5794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (vp8AndroidParams->eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
5804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mTemporalLayers = vp8AndroidParams->nTemporalLayerCount;
5814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    } else if (vp8AndroidParams->eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternNone) {
5824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mTemporalLayers = 0;
5834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
5844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    // Check the bitrate distribution between layers is in increasing order
5854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (mTemporalLayers > 1) {
5864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        for (size_t i = 0; i < mTemporalLayers - 1; i++) {
5874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            if (vp8AndroidParams->nTemporalLayerBitrateRatio[i + 1] <=
5884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    vp8AndroidParams->nTemporalLayerBitrateRatio[i]) {
5894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                ALOGE("Wrong bitrate ratio - should be in increasing order.");
5904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                return OMX_ErrorBadParameter;
5914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
5924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
5934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
5944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mKeyFrameInterval = vp8AndroidParams->nKeyFrameInterval;
5954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mMinQuantizer = vp8AndroidParams->nMinQuantizer;
5964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mMaxQuantizer = vp8AndroidParams->nMaxQuantizer;
5974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    memcpy(mTemporalLayerBitrateRatio, vp8AndroidParams->nTemporalLayerBitrateRatio,
5984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            sizeof(mTemporalLayerBitrateRatio));
5994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    ALOGD("VP8: internalSetAndroidVp8Params. BRMode: %u. TS: %zu. KF: %u."
6004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev          " QP: %u - %u BR0: %u. BR1: %u. BR2: %u",
6014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev          (uint32_t)mBitrateControlMode, mTemporalLayers, mKeyFrameInterval,
6024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev          mMinQuantizer, mMaxQuantizer, mTemporalLayerBitrateRatio[0],
6034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev          mTemporalLayerBitrateRatio[1], mTemporalLayerBitrateRatio[2]);
6044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    return OMX_ErrorNone;
6054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev}
606b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
607b4698f79230bbee15936641d951d49655f9e6da5Kunter GultekinOMX_ERRORTYPE SoftVPXEncoder::internalSetBitrateParams(
608b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        const OMX_VIDEO_PARAM_BITRATETYPE* bitrate) {
609b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (bitrate->nPortIndex != kOutputPortIndex) {
610b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        return OMX_ErrorUnsupportedIndex;
611b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
612b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
613b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    mBitrate = bitrate->nTargetBitrate;
614b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
615b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (bitrate->eControlRate == OMX_Video_ControlRateVariable) {
616b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mBitrateControlMode = VPX_VBR;
617b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    } else if (bitrate->eControlRate == OMX_Video_ControlRateConstant) {
618b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        mBitrateControlMode = VPX_CBR;
619b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    } else {
620b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        return OMX_ErrorUnsupportedSetting;
621b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
622b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
623b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    return OMX_ErrorNone;
624b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
625b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
6264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznevvpx_enc_frame_flags_t SoftVPXEncoder::getEncodeFlags() {
6274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vpx_enc_frame_flags_t flags = 0;
6284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int patternIdx = mTemporalPatternIdx % mTemporalPatternLength;
6294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    mTemporalPatternIdx++;
6304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    switch (mTemporalPattern[patternIdx]) {
6314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateLast:
6324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_GF;
6334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_ARF;
6364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateGoldenWithoutDependency:
6384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            // Deliberately no break here.
6404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateGolden:
6414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_ARF;
6424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_LAST;
6444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateAltrefWithoutDependency:
6464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_ARF;
6474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            // Deliberately no break here.
6494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateAltref:
6504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_GF;
6514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_LAST;
6524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateNoneNoRefAltref:
6544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_ARF;
6554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            // Deliberately no break here.
6564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateNone:
6574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_GF;
6584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_LAST;
6604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ENTROPY;
6614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateNoneNoRefGoldenRefAltRef:
6634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_GF;
6654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_LAST;
6674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ENTROPY;
6684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateGoldenWithoutDependencyRefAltRef:
6704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_LAST;
6734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateLastRefAltRef:
6754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_GF;
6764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateGoldenRefAltRef:
6804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_LAST;
6824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateLastAndGoldenRefAltRef:
6844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_REF_GF;
6864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        case kTemporalUpdateLastRefAll:
6884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_ARF;
6894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags |= VP8_EFLAG_NO_UPD_GF;
6904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            break;
6914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
6924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    return flags;
6934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev}
694b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
695a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnarvoid SoftVPXEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
696b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    // Initialize encoder if not already
697b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    if (mCodecContext == NULL) {
698b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        if (OK != initEncoder()) {
699b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            ALOGE("Failed to initialize encoder");
700b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            notify(OMX_EventError,
701b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                   OMX_ErrorUndefined,
702b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                   0,  // Extra notification data
703b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                   NULL);  // Notification data pointer
704b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            return;
705b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
706b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
707b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
708b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    vpx_codec_err_t codec_return;
709b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    List<BufferInfo *> &inputBufferInfoQueue = getPortQueue(kInputPortIndex);
710b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    List<BufferInfo *> &outputBufferInfoQueue = getPortQueue(kOutputPortIndex);
711b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
712b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    while (!inputBufferInfoQueue.empty() && !outputBufferInfoQueue.empty()) {
713b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        BufferInfo *inputBufferInfo = *inputBufferInfoQueue.begin();
714b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        OMX_BUFFERHEADERTYPE *inputBufferHeader = inputBufferInfo->mHeader;
715b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
716b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        BufferInfo *outputBufferInfo = *outputBufferInfoQueue.begin();
717b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader;
718b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
7192d3ad4087c2231542f07854d3b9ff5b4cae9fd69Ronghua Wu        if ((inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) &&
7202d3ad4087c2231542f07854d3b9ff5b4cae9fd69Ronghua Wu                inputBufferHeader->nFilledLen == 0) {
721b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            inputBufferInfoQueue.erase(inputBufferInfoQueue.begin());
722b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            inputBufferInfo->mOwnedByUs = false;
723b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            notifyEmptyBufferDone(inputBufferHeader);
724b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
725b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            outputBufferHeader->nFilledLen = 0;
726b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            outputBufferHeader->nFlags = OMX_BUFFERFLAG_EOS;
727b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
728b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            outputBufferInfoQueue.erase(outputBufferInfoQueue.begin());
729b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            outputBufferInfo->mOwnedByUs = false;
730b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            notifyFillBufferDone(outputBufferHeader);
731b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            return;
732b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
733b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
7342edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar        const uint8_t *source =
735a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber            inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
736a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber
737e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim        size_t frameSize = mWidth * mHeight * 3 / 2;
738a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber        if (mInputDataIsMeta) {
7392edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            source = extractGraphicBuffer(
740e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                    mConversionBuffer, frameSize,
7412edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    source, inputBufferHeader->nFilledLen,
7422edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                    mWidth, mHeight);
7432edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar            if (source == NULL) {
7442edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                ALOGE("Unable to extract gralloc buffer in metadata mode");
7452edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
7462edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                return;
747a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber            }
748e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim        } else {
749e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim            if (inputBufferHeader->nFilledLen < frameSize) {
750e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                android_errorWriteLog(0x534e4554, "27569635");
751e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
752e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                return;
753e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim            } else if (inputBufferHeader->nFilledLen > frameSize) {
754e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                ALOGW("Input buffer contains too many pixels");
755e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim            }
756b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
757e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim            if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
758e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                ConvertYUV420SemiPlanarToYUV420Planar(
759e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                        source, mConversionBuffer, mWidth, mHeight);
760e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim
761e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                source = mConversionBuffer;
762e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim            }
763b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
764b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vpx_image_t raw_frame;
765b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, mWidth, mHeight,
7662edda09a2ad1d112c52acd37d323f63f0a492d67Lajos Molnar                     kInputBufferAlignment, (uint8_t *)source);
767336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber
768336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        vpx_enc_frame_flags_t flags = 0;
7694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (mTemporalPatternLength > 0) {
7704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            flags = getEncodeFlags();
7714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
772336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        if (mKeyFrameRequested) {
773336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            flags |= VPX_EFLAG_FORCE_KF;
774336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber            mKeyFrameRequested = false;
775336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber        }
776336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber
77730c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann        if (mBitrateUpdated) {
77830c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            mCodecConfiguration->rc_target_bitrate = mBitrate/1000;
77930c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            vpx_codec_err_t res = vpx_codec_enc_config_set(mCodecContext,
78030c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                                                           mCodecConfiguration);
78130c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            if (res != VPX_CODEC_OK) {
78230c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                ALOGE("vp8 encoder failed to update bitrate: %s",
78330c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                      vpx_codec_err_to_string(res));
78430c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                notify(OMX_EventError,
78530c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                       OMX_ErrorUndefined,
78630c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                       0, // Extra notification data
78730c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann                       NULL); // Notification data pointer
78830c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            }
78930c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann            mBitrateUpdated = false;
79030c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann        }
79130c08634416a99a0f627e4de3a5f49dcf0a72fd3Johann
7924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        uint32_t frameDuration;
7934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (inputBufferHeader->nTimeStamp > mLastTimestamp) {
7944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            frameDuration = (uint32_t)(inputBufferHeader->nTimeStamp - mLastTimestamp);
7954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
7964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            frameDuration = (uint32_t)(((uint64_t)1000000 << 16) / mFramerate);
7974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
7984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        mLastTimestamp = inputBufferHeader->nTimeStamp;
799a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber        codec_return = vpx_codec_encode(
800a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber                mCodecContext,
801a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber                &raw_frame,
802a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber                inputBufferHeader->nTimeStamp,  // in timebase units
8030d6abe8cdadde6f9ad7ac989042f725668233bdbAlex Glaznev                frameDuration,  // frame duration in timebase units
804336da16a12423c496efba6ca9813d5d42a1f70f6Andreas Huber                flags,  // frame flags
805a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber                VPX_DL_REALTIME);  // encoding deadline
806b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        if (codec_return != VPX_CODEC_OK) {
807b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            ALOGE("vpx encoder failed to encode frame");
808b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            notify(OMX_EventError,
809b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                   OMX_ErrorUndefined,
810b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                   0,  // Extra notification data
811b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                   NULL);  // Notification data pointer
812b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            return;
813b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
814b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
815b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        vpx_codec_iter_t encoded_packet_iterator = NULL;
816b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        const vpx_codec_cx_pkt_t* encoded_packet;
817b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
818a5761dcb5f9f017ca9b83ec868565d7ce54a92acAndreas Huber        while ((encoded_packet = vpx_codec_get_cx_data(
819a5761dcb5f9f017ca9b83ec868565d7ce54a92acAndreas Huber                        mCodecContext, &encoded_packet_iterator))) {
820b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            if (encoded_packet->kind == VPX_CODEC_CX_FRAME_PKT) {
821b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                outputBufferHeader->nTimeStamp = encoded_packet->data.frame.pts;
822b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                outputBufferHeader->nFlags = 0;
823465da60d885c8fa4e7cea4626478574ce17a54a9Johann                if (encoded_packet->data.frame.flags & VPX_FRAME_IS_KEY)
824e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                    outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
825b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                outputBufferHeader->nOffset = 0;
826b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                outputBufferHeader->nFilledLen = encoded_packet->data.frame.sz;
827e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                if (outputBufferHeader->nFilledLen > outputBufferHeader->nAllocLen) {
828e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                    android_errorWriteLog(0x534e4554, "27569635");
829e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                    notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
830e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                    return;
831e5b67490353efa67496d1c907edaab0cf5a41d2eWonsik Kim                }
832b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                memcpy(outputBufferHeader->pBuffer,
833b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                       encoded_packet->data.frame.buf,
834b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                       encoded_packet->data.frame.sz);
835b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                outputBufferInfo->mOwnedByUs = false;
836b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                outputBufferInfoQueue.erase(outputBufferInfoQueue.begin());
8372d3ad4087c2231542f07854d3b9ff5b4cae9fd69Ronghua Wu                if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) {
8382d3ad4087c2231542f07854d3b9ff5b4cae9fd69Ronghua Wu                    outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
8392d3ad4087c2231542f07854d3b9ff5b4cae9fd69Ronghua Wu                }
840b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin                notifyFillBufferDone(outputBufferHeader);
841b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin            }
842b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        }
843b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
844b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        inputBufferInfo->mOwnedByUs = false;
845b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        inputBufferInfoQueue.erase(inputBufferInfoQueue.begin());
846b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        notifyEmptyBufferDone(inputBufferHeader);
847b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    }
848b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
849a0a63e13788a77bc502da0c72269d82c4779ac91Andreas Huber
850b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}  // namespace android
851b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
852b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin
853b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekinandroid::SoftOMXComponent *createSoftOMXComponent(
854b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        const char *name, const OMX_CALLBACKTYPE *callbacks,
855b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
856b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin    return new android::SoftVPXEncoder(name, callbacks, appData, component);
857b4698f79230bbee15936641d951d49655f9e6da5Kunter Gultekin}
858