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"
2496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber#include <cutils/properties.h>
26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceTextureClient.h>
27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/ICrypto.h>
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
3196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#include <media/stagefright/MediaBuffer.h>
32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaCodec.h>
33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber#include <OMX_Video.h>
3796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::Converter(
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &notify,
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ALooper> &codecLooper,
43e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        const sp<AMessage> &format,
44e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio)
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mInitCheck(NO_INIT),
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mCodecLooper(codecLooper),
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mInputFormat(format),
49496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber      mIsVideo(false),
50e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber      mIsPCMAudio(usePCMAudio),
51cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      mDoMoreWorkPending(false)
52cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION
53cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      ,mFirstSilentFrameUs(-1ll)
54cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      ,mInSilentMode(false)
55cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif
56cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    {
57496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    AString mime;
58496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    CHECK(mInputFormat->findString("mime", &mime));
59496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
60496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!strncasecmp("video/", mime.c_str(), 6)) {
61496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        mIsVideo = true;
62496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
63496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
64e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!usePCMAudio || !mIsVideo);
65e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mInitCheck = initEncoder();
673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (mInitCheck != OK) {
693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (mEncoder != NULL) {
703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            mEncoder->release();
713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            mEncoder.clear();
723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() {
7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(mEncoder == NULL);
7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
79a438123bd96c7faf145683876702387efe5628d9Andreas Huber
8096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() {
8196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("shutdown");
8296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    (new AMessage(kWhatShutdown, id()))->post();
83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const {
86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mInitCheck;
87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
8966e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const {
9066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    return mEncoderInputBuffers.size();
9166e72bc85fb762876baff60ef29de729da93cf26Andreas Huber}
9266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const {
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mOutputFormat;
95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
9744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) {
9844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    char val[PROPERTY_VALUE_MAX];
9944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    if (property_get(propName, val, NULL)) {
10044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        char *end;
10144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        unsigned long x = strtoul(val, &end, 10);
10244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
10344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        if (*end == '\0' && end > val && x > 0) {
10444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber            return x;
10544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        }
10644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    }
10744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
10844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    return defaultValue;
10944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber}
11044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() {
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString inputMIME;
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(mInputFormat->findString("mime", &inputMIME));
114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString outputMIME;
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool isAudio = false;
117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
118e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mIsPCMAudio) {
119e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            outputMIME = MEDIA_MIMETYPE_AUDIO_RAW;
120e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        } else {
121e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            outputMIME = MEDIA_MIMETYPE_AUDIO_AAC;
122e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        isAudio = true;
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) {
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_VIDEO_AVC;
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        TRESPASS();
128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
130e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (!mIsPCMAudio) {
131e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        mEncoder = MediaCodec::CreateByType(
132e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mCodecLooper, outputMIME.c_str(), true /* encoder */);
133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
134e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mEncoder == NULL) {
135e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            return ERROR_UNSUPPORTED;
136e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat = mInputFormat->dup();
140e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
141e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
142e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return OK;
143e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
144e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat->setString("mime", outputMIME.c_str());
146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
147f58cac48e5732dbc4a5f33eed9cd39f109146ca4Dave Burke    int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000);
1482295ce2c6fcf07ffaa134440691a8cea5fe35b43Dave Burke    int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000);
14944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
15044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
15144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber          audioBitrate, videoBitrate);
15244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (isAudio) {
15444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", audioBitrate);
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
15644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", videoBitrate);
15796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant);
1584a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mOutputFormat->setInt32("frame-rate", 30);
159ee93c8c0f65cc1965ca09c9e33ae672f8bc9b88cDave Burke        mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
160c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber        mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1);
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->configure(
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mOutputFormat,
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* nativeWindow */,
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* crypto */,
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            MediaCodec::CONFIGURE_FLAG_ENCODE);
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->start();
176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) {
191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = mNotify->dup();
192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("what", kWhatError);
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("err", err);
194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->post();
195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
197cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber// static
198cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huberbool Converter::IsSilence(const sp<ABuffer> &accessUnit) {
199cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    const uint8_t *ptr = accessUnit->data();
200cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    const uint8_t *end = ptr + accessUnit->size();
201cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    while (ptr < end) {
202cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (*ptr != 0) {
203cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            return false;
204cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
205cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        ++ptr;
206cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    }
207cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
208cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    return true;
209cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber}
210cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) {
212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
21396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerNotify:
214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
21596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
218e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (!mIsPCMAudio && mEncoder == NULL) {
21996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                ALOGV("got msg '%s' after encoder shutdown.",
22096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                      msg->debugString().c_str());
221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
22296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (what == MediaPuller::kWhatAccessUnit) {
22396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    sp<ABuffer> accessUnit;
22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
22696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    void *mbuf;
22796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
22896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                            && mbuf != NULL) {
22996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        ALOGV("releasing mbuf %p", mbuf);
230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
23196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        accessUnit->meta()->setPointer("mediaBuffer", NULL);
23296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
23396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        static_cast<MediaBuffer *>(mbuf)->release();
23496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        mbuf = NULL;
23596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    }
23696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
23796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
23896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == MediaPuller::kWhatEOS) {
24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(NULL);
24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
24696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            } else {
24796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK_EQ(what, MediaPuller::kWhatAccessUnit);
24896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                sp<ABuffer> accessUnit;
25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
25196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
25296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0
25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                void *mbuf;
25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        && mbuf != NULL) {
25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    ALOGI("queueing mbuf %p", mbuf);
25796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
25896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif
25996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
260cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION
261cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                if (!mIsVideo) {
262cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    if (IsSilence(accessUnit)) {
2638d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        if (mInSilentMode) {
2648d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            break;
2658d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        }
2668d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber
2678d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        int64_t nowUs = ALooper::GetNowUs();
2688d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber
2698d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        if (mFirstSilentFrameUs < 0ll) {
2708d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            mFirstSilentFrameUs = nowUs;
2718d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) {
2728d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            mInSilentMode = true;
2738d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            ALOGI("audio in silent mode now.");
2748d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            break;
275cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        }
276cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    } else {
277cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        if (mInSilentMode) {
278cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                            ALOGI("audio no longer in silent mode.");
279cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        }
280cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        mInSilentMode = false;
281cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        mFirstSilentFrameUs = -1ll;
282cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    }
283cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                }
284cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif
285cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
28696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(accessUnit);
287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
28896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
29096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
29196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
295575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatEncoderActivity:
296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
297575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 0
298575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            int64_t whenUs;
299575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            if (msg->findInt64("whenUs", &whenUs)) {
300575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                int64_t nowUs = ALooper::GetNowUs();
301575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                ALOGI("[%s] kWhatEncoderActivity after %lld us",
302575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                      mIsVideo ? "video" : "audio", nowUs - whenUs);
303575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            }
304575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif
305575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mDoMoreWorkPending = false;
30796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
30896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
30996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
31096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
31196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = doMoreWork();
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err != OK) {
315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notifyError(err);
316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                scheduleDoMoreWork();
318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
322496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
323496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
32496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
32596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
32696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
32796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
328496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (mIsVideo) {
329496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGI("requesting IDR frame");
330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                mEncoder->requestIDRFrame();
331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
332496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
333496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
334496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
33596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatShutdown:
33696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
33796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("shutting down encoder");
338e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
339e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (mEncoder != NULL) {
340e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mEncoder->release();
341e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mEncoder.clear();
342e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
34396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
34496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            AString mime;
34596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(mInputFormat->findString("mime", &mime));
34696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("encoder (%s) shut down.", mime.c_str());
34796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
34896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
34996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() {
356e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
357e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        // There's no encoder involved in this case.
358e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return;
359e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
360e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mDoMoreWorkPending) {
362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mDoMoreWorkPending = true;
366575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
367575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 1
368575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mEncoderActivityNotify == NULL) {
369575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id());
370575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
371575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    mEncoder->requestActivityNotification(mEncoderActivityNotify->dup());
372575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#else
373575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id());
374575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    notify->setInt64("whenUs", ALooper::GetNowUs());
375575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    mEncoder->requestActivityNotification(notify);
376575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif
377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
379e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t Converter::feedRawAudioInputBuffers() {
380e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each
381e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    // and add a 4 byte header according to the wifi display specs.
382e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
383e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    while (!mInputBufferQueue.empty()) {
384e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
385e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
386e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
387e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        int16_t *ptr = (int16_t *)buffer->data();
388e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        int16_t *stop = (int16_t *)(buffer->data() + buffer->size());
389e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        while (ptr < stop) {
390e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            *ptr = htons(*ptr);
391e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ++ptr;
392e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
393e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
394e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kFrameSize = 2 * sizeof(int16_t);  // stereo
395e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kFramesPerAU = 80;
396e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kNumAUsPerPESPacket = 6;
397e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
398e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mPartialAudioAU != NULL) {
399e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t bytesMissingForFullAU =
400e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                kNumAUsPerPESPacket * kFramesPerAU * kFrameSize
401e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                - mPartialAudioAU->size() + 4;
402e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
403e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t copy = buffer->size();
404e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if(copy > bytesMissingForFullAU) {
405e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                copy = bytesMissingForFullAU;
406e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
407e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
408e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(),
409e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                   buffer->data(),
410e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                   copy);
411e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
412e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy);
413e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
414e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
415e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
416e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t timeUs;
417e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
418e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
419e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
420e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            timeUs += copyUs;
421e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
422e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
423e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (bytesMissingForFullAU == copy) {
424e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                sp<AMessage> notify = mNotify->dup();
425e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setInt32("what", kWhatAccessUnit);
426e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setBuffer("accessUnit", mPartialAudioAU);
427e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->post();
428e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
429e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mPartialAudioAU.clear();
430e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
431e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
432e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
433e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        while (buffer->size() > 0) {
434e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            sp<ABuffer> partialAudioAU =
435e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                new ABuffer(
436e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                        4
437e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                        + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU);
438e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
439e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            uint8_t *ptr = partialAudioAU->data();
440e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[0] = 0xa0;  // 10100000b
441e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[1] = kNumAUsPerPESPacket;
442e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[2] = 0;  // reserved, audio _emphasis_flag = 0
443e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
444e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kQuantizationWordLength = 0;  // 16-bit
445e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kAudioSamplingFrequency = 2;  // 48Khz
446e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kNumberOfAudioChannels = 1;  // stereo
447e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
448e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[3] = (kQuantizationWordLength << 6)
449e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                    | (kAudioSamplingFrequency << 3)
450e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                    | kNumberOfAudioChannels;
451e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
452e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t copy = buffer->size();
453e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (copy > partialAudioAU->size() - 4) {
454e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                copy = partialAudioAU->size() - 4;
455e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
456e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
457e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            memcpy(&ptr[4], buffer->data(), copy);
458e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
459e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            partialAudioAU->setRange(0, 4 + copy);
460e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
461e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
462e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t timeUs;
463e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
464e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
465e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            partialAudioAU->meta()->setInt64("timeUs", timeUs);
466e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
467e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
468e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            timeUs += copyUs;
469e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
470e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
47190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (copy == partialAudioAU->capacity() - 4) {
472e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                sp<AMessage> notify = mNotify->dup();
473e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setInt32("what", kWhatAccessUnit);
474e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setBuffer("accessUnit", partialAudioAU);
475e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->post();
476e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
477e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                partialAudioAU.clear();
478e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                continue;
479e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
480e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
481e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            mPartialAudioAU = partialAudioAU;
482e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
483e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
484e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
485e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return OK;
486e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber}
487e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() {
489e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
490e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return feedRawAudioInputBuffers();
491e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
492e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (!mInputBufferQueue.empty()
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && !mAvailEncoderInputIndices.empty()) {
495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t timeUs = 0ll;
502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t flags = 0;
503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (buffer != NULL) {
505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->data(),
509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->size());
510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            void *mediaBuffer;
512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    && mediaBuffer != NULL) {
514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ->setPointer("mediaBuffer", mediaBuffer);
516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                buffer->meta()->setPointer("mediaBuffer", NULL);
518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            flags = MediaCodec::BUFFER_FLAG_EOS;
521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = mEncoder->queueInputBuffer(
524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs, flags);
526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() {
536575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    status_t err;
537575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
538575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    for (;;) {
539575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        size_t bufferIndex;
540575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        err = mEncoder->dequeueInputBuffer(&bufferIndex);
541575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
542575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        if (err != OK) {
543575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
544575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.push_back(bufferIndex);
547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
549575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    feedEncoderInputBuffers();
550575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
551cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    for (;;) {
552575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        size_t bufferIndex;
553cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        size_t offset;
554cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        size_t size;
555cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        int64_t timeUs;
556cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        uint32_t flags;
557cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        err = mEncoder->dequeueOutputBuffer(
558cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                &bufferIndex, &offset, &size, &timeUs, &flags);
559cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
560cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (err != OK) {
561cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            if (err == -EAGAIN) {
562cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                err = OK;
563cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            }
564cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            break;
565cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatEOS);
570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> buffer = new ABuffer(size);
573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5758d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber            ALOGV("[%s] time %lld us (%.2f secs)",
5768d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                  mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6);
577cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(buffer->data(),
579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   size);
581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mOutputFormat->setBuffer("csd-0", buffer);
584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> notify = mNotify->dup();
586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setInt32("what", kWhatAccessUnit);
587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setBuffer("accessUnit", buffer);
588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->post();
589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
592cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        mEncoder->releaseOutputBuffer(bufferIndex);
593cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
594cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
595cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            break;
596cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return err;
600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
602496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() {
603496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
604496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
605496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
607