1d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber/*
2d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Copyright 2012, The Android Open Source Project
3d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *
4d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * you may not use this file except in compliance with the License.
6d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * You may obtain a copy of the License at
7d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *
8d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *
10d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Unless required by applicable law or agreed to in writing, software
11d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * See the License for the specific language governing permissions and
14d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * limitations under the License.
15d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber */
16d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
17d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//#define LOG_NDEBUG 0
18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define LOG_TAG "Converter"
19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <utils/Log.h>
20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
21d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "Converter.h"
22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#include "MediaPuller.h"
24a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber#include "include/avc_utils.h"
2596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber#include <cutils/properties.h>
271a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/ICrypto.h>
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
3296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#include <media/stagefright/MediaBuffer.h>
33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaCodec.h>
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
37a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber#include <arpa/inet.h>
38a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
3996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber#include <OMX_Video.h>
4096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::Converter(
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &notify,
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ALooper> &codecLooper,
46a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        const sp<AMessage> &outputFormat,
47a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        uint32_t flags)
48a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    : mNotify(notify),
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mCodecLooper(codecLooper),
509fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber      mOutputFormat(outputFormat),
51a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber      mFlags(flags),
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber      mIsVideo(false),
53a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber      mIsH264(false),
549fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber      mIsPCMAudio(false),
550224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber      mNeedToManuallyPrependSPSPPS(false),
56cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      mDoMoreWorkPending(false)
57cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION
58cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      ,mFirstSilentFrameUs(-1ll)
59cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      ,mInSilentMode(false)
60cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif
61a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber      ,mPrevVideoBitrate(-1)
62126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber      ,mNumFramesToDrop(0)
63a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber      ,mEncodingSuspended(false)
64cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    {
65496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    AString mime;
669fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
67496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
68496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!strncasecmp("video/", mime.c_str(), 6)) {
69496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        mIsVideo = true;
70a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
71a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        mIsH264 = !strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC);
729fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime.c_str())) {
739fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber        mIsPCMAudio = true;
74496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
75c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber}
76c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber
77c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Hubervoid Converter::releaseEncoder() {
78c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber    if (mEncoder == NULL) {
79c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber        return;
80c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber    }
81c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber
82c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber    mEncoder->release();
83c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber    mEncoder.clear();
84c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber
8596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    mInputBufferQueue.clear();
86c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber    mEncoderInputBuffers.clear();
87c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber    mEncoderOutputBuffers.clear();
88c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber}
89c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber
90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() {
9196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(mEncoder == NULL);
9296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
93a438123bd96c7faf145683876702387efe5628d9Andreas Huber
9496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() {
9596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("shutdown");
961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatShutdown, this))->post();
97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
99a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huberstatus_t Converter::init() {
100a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    status_t err = initEncoder();
101a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
102a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    if (err != OK) {
103a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        releaseEncoder();
104a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    }
105a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
106a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    return err;
107a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber}
108a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
109a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Hubersp<IGraphicBufferProducer> Converter::getGraphicBufferProducer() {
110a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
111a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    return mGraphicBufferProducer;
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
11466e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const {
11566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    return mEncoderInputBuffers.size();
11666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber}
11766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const {
119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mOutputFormat;
120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1220224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huberbool Converter::needToManuallyPrependSPSPPS() const {
1230224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    return mNeedToManuallyPrependSPSPPS;
1240224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber}
1250224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
126eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber// static
127eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huberint32_t Converter::GetInt32Property(
128eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber        const char *propName, int32_t defaultValue) {
12944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    char val[PROPERTY_VALUE_MAX];
13044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    if (property_get(propName, val, NULL)) {
13144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        char *end;
13244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        unsigned long x = strtoul(val, &end, 10);
13344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
13444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        if (*end == '\0' && end > val && x > 0) {
13544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber            return x;
13644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        }
13744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    }
13844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
13944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    return defaultValue;
14044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber}
14144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() {
143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString outputMIME;
1449fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber    CHECK(mOutputFormat->findString("mime", &outputMIME));
1459fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber
1469fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber    bool isAudio = !strncasecmp(outputMIME.c_str(), "audio/", 6);
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
148e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (!mIsPCMAudio) {
149e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        mEncoder = MediaCodec::CreateByType(
150e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mCodecLooper, outputMIME.c_str(), true /* encoder */);
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
152e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mEncoder == NULL) {
153e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            return ERROR_UNSUPPORTED;
154e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
157e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
158e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return OK;
159e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
160e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
161eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber    int32_t audioBitrate = GetInt32Property("media.wfd.audio-bitrate", 128000);
162eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber    int32_t videoBitrate = GetInt32Property("media.wfd.video-bitrate", 5000000);
163a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mPrevVideoBitrate = videoBitrate;
16444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
16544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
16644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber          audioBitrate, videoBitrate);
16744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (isAudio) {
16944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", audioBitrate);
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
17144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", videoBitrate);
17296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant);
1734a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mOutputFormat->setInt32("frame-rate", 30);
17413e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        mOutputFormat->setInt32("i-frame-interval", 15);  // Iframes every 15 secs
17513e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong
17613e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        // Configure encoder to use intra macroblock refresh mode
17713e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic);
17813e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong
17913e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        int width, height, mbs;
18013e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        if (!mOutputFormat->findInt32("width", &width)
18113e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong                || !mOutputFormat->findInt32("height", &height)) {
18213e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong            return ERROR_UNSUPPORTED;
18313e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        }
18413e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong
18513e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        // Update macroblocks in a cyclic fashion with 10% of all MBs within
18613e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        // frame gets updated at one time. It takes about 10 frames to
18713e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        // completely update a whole video frame. If the frame rate is 30,
18813e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        // it takes about 333 ms in the best case (if next frame is not an IDR)
18913e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        // to recover from a lost/corrupted packet.
19013e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100;
19113e8a0e8a14faaf3fe0bcebf4da1f2694d59565dJames Dong        mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs);
192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1960224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    mNeedToManuallyPrependSPSPPS = false;
1970224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
1980224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    status_t err = NO_INIT;
1990224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
2000224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    if (!isAudio) {
2010224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        sp<AMessage> tmp = mOutputFormat->dup();
2020224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        tmp->setInt32("prepend-sps-pps-to-idr-frames", 1);
2030224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
2040224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        err = mEncoder->configure(
2050224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                tmp,
2060224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                NULL /* nativeWindow */,
2070224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                NULL /* crypto */,
2080224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                MediaCodec::CONFIGURE_FLAG_ENCODE);
2090224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
2100224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        if (err == OK) {
2110224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber            // Encoder supported prepending SPS/PPS, we don't need to emulate
2120224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber            // it.
2130224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber            mOutputFormat = tmp;
2140224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        } else {
2150224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber            mNeedToManuallyPrependSPSPPS = true;
2160224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
2170224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber            ALOGI("We going to manually prepend SPS and PPS to IDR frames.");
2180224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        }
2190224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    }
2200224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
2210224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    if (err != OK) {
2220224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        // We'll get here for audio or if we failed to configure the encoder
2230224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        // to automatically prepend SPS/PPS in the case of video.
2240224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
2250224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        err = mEncoder->configure(
2260224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                    mOutputFormat,
2270224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                    NULL /* nativeWindow */,
2280224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                    NULL /* crypto */,
2290224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber                    MediaCodec::CONFIGURE_FLAG_ENCODE);
2300224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    }
231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
236a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    if (mFlags & FLAG_USE_SURFACE_INPUT) {
237a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        CHECK(mIsVideo);
238a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
239a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        err = mEncoder->createInputSurface(&mGraphicBufferProducer);
240a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
241a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        if (err != OK) {
242a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            return err;
243a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        }
244a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    }
245a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->start();
247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
258a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    err = mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
259a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
260a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    if (err != OK) {
261a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        return err;
262a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    }
263a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
264a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    if (mFlags & FLAG_USE_SURFACE_INPUT) {
265a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        scheduleDoMoreWork();
266a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    }
267a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
268a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    return OK;
269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) {
272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = mNotify->dup();
273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("what", kWhatError);
274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("err", err);
275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->post();
276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
278cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber// static
279cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huberbool Converter::IsSilence(const sp<ABuffer> &accessUnit) {
280cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    const uint8_t *ptr = accessUnit->data();
281cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    const uint8_t *end = ptr + accessUnit->size();
282cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    while (ptr < end) {
283cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (*ptr != 0) {
284cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            return false;
285cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
286cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        ++ptr;
287cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    }
288cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
289cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    return true;
290cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber}
291cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) {
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
29496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerNotify:
295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
29696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
29796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
299e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (!mIsPCMAudio && mEncoder == NULL) {
30096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                ALOGV("got msg '%s' after encoder shutdown.",
30196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                      msg->debugString().c_str());
302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
30396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (what == MediaPuller::kWhatAccessUnit) {
30496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    sp<ABuffer> accessUnit;
30596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
30796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                    accessUnit->setMediaBufferBase(NULL);
30896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
30996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
31096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
31196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
31296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == MediaPuller::kWhatEOS) {
31396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(NULL);
31496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
31596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
31696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
31796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
31896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            } else {
31996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK_EQ(what, MediaPuller::kWhatAccessUnit);
32096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
32196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                sp<ABuffer> accessUnit;
32296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
32396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
324a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                if (mNumFramesToDrop > 0 || mEncodingSuspended) {
325a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                    if (mNumFramesToDrop > 0) {
326a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                        --mNumFramesToDrop;
327a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                        ALOGI("dropping frame.");
328a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                    }
329a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
33096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                    accessUnit->setMediaBufferBase(NULL);
331126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                    break;
332126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                }
333126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
33496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0
33596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                MediaBuffer *mbuf =
33696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                    (MediaBuffer *)(accessUnit->getMediaBufferBase());
33796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                if (mbuf != NULL) {
33896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    ALOGI("queueing mbuf %p", mbuf);
33996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                    mbuf->release();
34096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
34196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif
34296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
343cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION
344cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                if (!mIsVideo) {
345cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    if (IsSilence(accessUnit)) {
3468d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        if (mInSilentMode) {
3478d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            break;
3488d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        }
3498d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber
3508d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        int64_t nowUs = ALooper::GetNowUs();
3518d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber
3528d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        if (mFirstSilentFrameUs < 0ll) {
3538d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            mFirstSilentFrameUs = nowUs;
3548d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) {
3558d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            mInSilentMode = true;
3568d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            ALOGI("audio in silent mode now.");
3578d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            break;
358cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        }
359cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    } else {
360cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        if (mInSilentMode) {
361cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                            ALOGI("audio no longer in silent mode.");
362cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        }
363cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        mInSilentMode = false;
364cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        mFirstSilentFrameUs = -1ll;
365cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    }
366cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                }
367cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif
368cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
36996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(accessUnit);
370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
37196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
37396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
37496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
378575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatEncoderActivity:
379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
380575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 0
381575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            int64_t whenUs;
382575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            if (msg->findInt64("whenUs", &whenUs)) {
383575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                int64_t nowUs = ALooper::GetNowUs();
384575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                ALOGI("[%s] kWhatEncoderActivity after %lld us",
385575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                      mIsVideo ? "video" : "audio", nowUs - whenUs);
386575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            }
387575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif
388575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mDoMoreWorkPending = false;
39096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
39196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
39296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
39396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
39496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = doMoreWork();
396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err != OK) {
398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notifyError(err);
399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                scheduleDoMoreWork();
401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
405496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
406496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
40796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
40896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
40996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
41096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
411496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (mIsVideo) {
412a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                ALOGV("requesting IDR frame");
413496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                mEncoder->requestIDRFrame();
414496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
415496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
416496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
417496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
41896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatShutdown:
41996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
420c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber            ALOGI("shutting down %s encoder", mIsVideo ? "video" : "audio");
421e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
422c8e07e483c116ecaca1c9c6991588607f1187b75Andreas Huber            releaseEncoder();
42396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
42496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            AString mime;
4259fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber            CHECK(mOutputFormat->findString("mime", &mime));
42696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("encoder (%s) shut down.", mime.c_str());
427a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
428a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            sp<AMessage> notify = mNotify->dup();
429a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            notify->setInt32("what", kWhatShutdownCompleted);
430a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            notify->post();
43196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
43296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
43396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
434126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        case kWhatDropAFrame:
435126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        {
436126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            ++mNumFramesToDrop;
437126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            break;
438126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        }
439126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
440308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        case kWhatReleaseOutputBuffer:
441308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        {
442308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mEncoder != NULL) {
443308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                size_t bufferIndex;
444308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                CHECK(msg->findInt32("bufferIndex", (int32_t*)&bufferIndex));
445308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                CHECK(bufferIndex < mEncoderOutputBuffers.size());
446308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mEncoder->releaseOutputBuffer(bufferIndex);
447308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
448308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            break;
449308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
450308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
451a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        case kWhatSuspendEncoding:
452a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        {
453a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            int32_t suspend;
454a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            CHECK(msg->findInt32("suspend", &suspend));
455a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
456a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            mEncodingSuspended = suspend;
457a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
458a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            if (mFlags & FLAG_USE_SURFACE_INPUT) {
459a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                sp<AMessage> params = new AMessage;
460a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                params->setInt32("drop-input-frames",suspend);
461a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                mEncoder->setParameters(params);
462a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            }
463a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            break;
464a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        }
465a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() {
472e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
473e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        // There's no encoder involved in this case.
474e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return;
475e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
476e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mDoMoreWorkPending) {
478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mDoMoreWorkPending = true;
482575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
483575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 1
484575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mEncoderActivityNotify == NULL) {
4851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, this);
486575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
487575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    mEncoder->requestActivityNotification(mEncoderActivityNotify->dup());
488575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#else
4891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatEncoderActivity, this);
490575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    notify->setInt64("whenUs", ALooper::GetNowUs());
491575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    mEncoder->requestActivityNotification(notify);
492575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif
493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
495e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t Converter::feedRawAudioInputBuffers() {
496e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each
497e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    // and add a 4 byte header according to the wifi display specs.
498e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
499e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    while (!mInputBufferQueue.empty()) {
500e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
501e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
502e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
503e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        int16_t *ptr = (int16_t *)buffer->data();
504e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        int16_t *stop = (int16_t *)(buffer->data() + buffer->size());
505e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        while (ptr < stop) {
506e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            *ptr = htons(*ptr);
507e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ++ptr;
508e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
509e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
510e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kFrameSize = 2 * sizeof(int16_t);  // stereo
511e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kFramesPerAU = 80;
512e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kNumAUsPerPESPacket = 6;
513e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
514e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mPartialAudioAU != NULL) {
515e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t bytesMissingForFullAU =
516e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                kNumAUsPerPESPacket * kFramesPerAU * kFrameSize
517e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                - mPartialAudioAU->size() + 4;
518e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
519e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t copy = buffer->size();
520e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if(copy > bytesMissingForFullAU) {
521e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                copy = bytesMissingForFullAU;
522e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
523e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
524e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(),
525e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                   buffer->data(),
526e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                   copy);
527e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
528e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy);
529e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
530e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
531e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
532e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t timeUs;
533e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
534e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
535e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
536e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            timeUs += copyUs;
537e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
538e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
539e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (bytesMissingForFullAU == copy) {
540e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                sp<AMessage> notify = mNotify->dup();
541e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setInt32("what", kWhatAccessUnit);
542e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setBuffer("accessUnit", mPartialAudioAU);
543e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->post();
544e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
545e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mPartialAudioAU.clear();
546e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
547e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
548e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
549e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        while (buffer->size() > 0) {
550e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            sp<ABuffer> partialAudioAU =
551e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                new ABuffer(
552e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                        4
553e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                        + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU);
554e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
555e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            uint8_t *ptr = partialAudioAU->data();
556e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[0] = 0xa0;  // 10100000b
557e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[1] = kNumAUsPerPESPacket;
558e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[2] = 0;  // reserved, audio _emphasis_flag = 0
559e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
560e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kQuantizationWordLength = 0;  // 16-bit
561e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kAudioSamplingFrequency = 2;  // 48Khz
562e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kNumberOfAudioChannels = 1;  // stereo
563e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
564e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[3] = (kQuantizationWordLength << 6)
565e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                    | (kAudioSamplingFrequency << 3)
566e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                    | kNumberOfAudioChannels;
567e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
568e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t copy = buffer->size();
569e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (copy > partialAudioAU->size() - 4) {
570e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                copy = partialAudioAU->size() - 4;
571e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
572e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
573e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            memcpy(&ptr[4], buffer->data(), copy);
574e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
575e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            partialAudioAU->setRange(0, 4 + copy);
576e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
577e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
578e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t timeUs;
579e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
580e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
581e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            partialAudioAU->meta()->setInt64("timeUs", timeUs);
582e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
583e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
584e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            timeUs += copyUs;
585e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
586e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
58790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (copy == partialAudioAU->capacity() - 4) {
588e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                sp<AMessage> notify = mNotify->dup();
589e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setInt32("what", kWhatAccessUnit);
590e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setBuffer("accessUnit", partialAudioAU);
591e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->post();
592e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
593e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                partialAudioAU.clear();
594e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                continue;
595e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
596e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
597e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            mPartialAudioAU = partialAudioAU;
598e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
599e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
600e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
601e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return OK;
602e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber}
603e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() {
605e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
606e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return feedRawAudioInputBuffers();
607e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
608e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (!mInputBufferQueue.empty()
610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && !mAvailEncoderInputIndices.empty()) {
611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t timeUs = 0ll;
618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t flags = 0;
619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (buffer != NULL) {
621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->data(),
625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->size());
626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
62796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia            MediaBuffer *mediaBuffer =
62896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                (MediaBuffer *)(buffer->getMediaBufferBase());
62996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia            if (mediaBuffer != NULL) {
63096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                mEncoderInputBuffers.itemAt(bufferIndex)->setMediaBufferBase(
63196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                        mediaBuffer);
632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
63396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia                buffer->setMediaBufferBase(NULL);
634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            flags = MediaCodec::BUFFER_FLAG_EOS;
637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = mEncoder->queueInputBuffer(
640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs, flags);
642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
651a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Hubersp<ABuffer> Converter::prependCSD(const sp<ABuffer> &accessUnit) const {
652a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    CHECK(mCSD0 != NULL);
653a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
654a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    sp<ABuffer> dup = new ABuffer(accessUnit->size() + mCSD0->size());
655a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    memcpy(dup->data(), mCSD0->data(), mCSD0->size());
656a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    memcpy(dup->data() + mCSD0->size(), accessUnit->data(), accessUnit->size());
657a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
658a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    int64_t timeUs;
659a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
660a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
661a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    dup->meta()->setInt64("timeUs", timeUs);
662a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
663a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    return dup;
664a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber}
665a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() {
667575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    status_t err;
668575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
669a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
670a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        for (;;) {
671a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            size_t bufferIndex;
672a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            err = mEncoder->dequeueInputBuffer(&bufferIndex);
673575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
674a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            if (err != OK) {
675a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                break;
676a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            }
677a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
678a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            mAvailEncoderInputIndices.push_back(bufferIndex);
679575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
681a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        feedEncoderInputBuffers();
682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
684cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    for (;;) {
685575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        size_t bufferIndex;
686cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        size_t offset;
687cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        size_t size;
688cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        int64_t timeUs;
689cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        uint32_t flags;
690308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        native_handle_t* handle = NULL;
691cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        err = mEncoder->dequeueOutputBuffer(
692cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                &bufferIndex, &offset, &size, &timeUs, &flags);
693cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
694cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (err != OK) {
695b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber            if (err == INFO_FORMAT_CHANGED) {
696b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber                continue;
697b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
698b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber                mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
699b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber                continue;
700b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber            }
701b489b1639c0c12fdd498def46d3f5be3e1fdf6b9Andreas Huber
702cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            if (err == -EAGAIN) {
703cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                err = OK;
704cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            }
705cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            break;
706cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatEOS);
711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
7139fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber#if 0
7149fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber            if (mIsVideo) {
7159fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber                int32_t videoBitrate = GetInt32Property(
7169fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber                        "media.wfd.video-bitrate", 5000000);
7179fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber
7189fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber                setVideoBitrate(videoBitrate);
7199fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber            }
7209fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber#endif
7219fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber
722308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            sp<ABuffer> buffer;
723308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            sp<ABuffer> outbuf = mEncoderOutputBuffers.itemAt(bufferIndex);
724308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
725308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (outbuf->meta()->findPointer("handle", (void**)&handle) &&
726308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    handle != NULL) {
727308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                int32_t rangeLength, rangeOffset;
728308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                CHECK(outbuf->meta()->findInt32("rangeOffset", &rangeOffset));
729308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                CHECK(outbuf->meta()->findInt32("rangeLength", &rangeLength));
730308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                outbuf->meta()->setPointer("handle", NULL);
731308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
732308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                // MediaSender will post the following message when HDCP
733308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                // is done, to release the output buffer back to encoder.
7341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                sp<AMessage> notify(new AMessage(kWhatReleaseOutputBuffer, this));
735308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                notify->setInt32("bufferIndex", bufferIndex);
736308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
737308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                buffer = new ABuffer(
738308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        rangeLength > (int32_t)size ? rangeLength : size);
739308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                buffer->meta()->setPointer("handle", handle);
740308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                buffer->meta()->setInt32("rangeOffset", rangeOffset);
741308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                buffer->meta()->setInt32("rangeLength", rangeLength);
742308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                buffer->meta()->setMessage("notify", notify);
743308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
744308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                buffer = new ABuffer(size);
745308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
746308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
7498d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber            ALOGV("[%s] time %lld us (%.2f secs)",
750ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    mIsVideo ? "video" : "audio", (long long)timeUs, timeUs / 1E6);
751cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
752308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            memcpy(buffer->data(), outbuf->base() + offset, size);
753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
755308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if (!handle) {
756a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                    if (mIsH264) {
757a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                        mCSD0 = buffer;
758a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                    }
759308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mOutputFormat->setBuffer("csd-0", buffer);
760308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                }
761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
762a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                if (mNeedToManuallyPrependSPSPPS
763a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                        && mIsH264
764a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                        && (mFlags & FLAG_PREPEND_CSD_IF_NECESSARY)
765a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                        && IsIDR(buffer)) {
766a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                    buffer = prependCSD(buffer);
767a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber                }
768a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> notify = mNotify->dup();
770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setInt32("what", kWhatAccessUnit);
771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setBuffer("accessUnit", buffer);
772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->post();
773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
776308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (!handle) {
777308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mEncoder->releaseOutputBuffer(bufferIndex);
778308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
779cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
780cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
781cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            break;
782cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return err;
786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
788496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() {
7891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
790496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
791496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
792126568c7aeeb5570789e70a310477f44dbdbd885Andreas Hubervoid Converter::dropAFrame() {
793a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    // Unsupported in surface input mode.
794a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    CHECK(!(mFlags & FLAG_USE_SURFACE_INPUT));
795a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
7961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatDropAFrame, this))->post();
797126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber}
798126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
799a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Hubervoid Converter::suspendEncoding(bool suspend) {
8001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSuspendEncoding, this);
801a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    msg->setInt32("suspend", suspend);
802a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    msg->post();
803a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber}
804a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
8052aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huberint32_t Converter::getVideoBitrate() const {
8062aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber    return mPrevVideoBitrate;
8072aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber}
8082aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber
8092aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Hubervoid Converter::setVideoBitrate(int32_t bitRate) {
8102aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber    if (mIsVideo && mEncoder != NULL && bitRate != mPrevVideoBitrate) {
8112aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        sp<AMessage> params = new AMessage;
812530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar        params->setInt32("video-bitrate", bitRate);
8132aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber
8142aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        mEncoder->setParameters(params);
8152aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber
8162aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        mPrevVideoBitrate = bitRate;
8172aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber    }
8182aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber}
8192aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber
820d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
821