Converter.cpp revision e7bd24af08ef0722fb124a550662bcec48c56f86
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
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::Converter(
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &notify,
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ALooper> &codecLooper,
41e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        const sp<AMessage> &format,
42e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio)
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mInitCheck(NO_INIT),
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mCodecLooper(codecLooper),
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mInputFormat(format),
47496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber      mIsVideo(false),
48e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber      mIsPCMAudio(usePCMAudio),
49cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      mDoMoreWorkPending(false)
50cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION
51cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      ,mFirstSilentFrameUs(-1ll)
52cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber      ,mInSilentMode(false)
53cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif
54cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    {
55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    AString mime;
56496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    CHECK(mInputFormat->findString("mime", &mime));
57496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
58496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!strncasecmp("video/", mime.c_str(), 6)) {
59496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        mIsVideo = true;
60496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
61496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
62e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!usePCMAudio || !mIsVideo);
63e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mInitCheck = initEncoder();
653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (mInitCheck != OK) {
673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (mEncoder != NULL) {
683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            mEncoder->release();
693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            mEncoder.clear();
703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() {
7596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(mEncoder == NULL);
7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
77a438123bd96c7faf145683876702387efe5628d9Andreas Huber
7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() {
7996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("shutdown");
8096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    (new AMessage(kWhatShutdown, id()))->post();
81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const {
84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mInitCheck;
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
8766e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const {
8866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    return mEncoderInputBuffers.size();
8966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber}
9066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const {
92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mOutputFormat;
93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
9544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) {
9644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    char val[PROPERTY_VALUE_MAX];
9744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    if (property_get(propName, val, NULL)) {
9844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        char *end;
9944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        unsigned long x = strtoul(val, &end, 10);
10044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
10144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        if (*end == '\0' && end > val && x > 0) {
10244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber            return x;
10344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        }
10444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    }
10544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
10644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    return defaultValue;
10744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber}
10844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() {
110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString inputMIME;
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(mInputFormat->findString("mime", &inputMIME));
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString outputMIME;
114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool isAudio = false;
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
116e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mIsPCMAudio) {
117e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            outputMIME = MEDIA_MIMETYPE_AUDIO_RAW;
118e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        } else {
119e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            outputMIME = MEDIA_MIMETYPE_AUDIO_AAC;
120e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        isAudio = true;
122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) {
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_VIDEO_AVC;
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        TRESPASS();
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
128e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (!mIsPCMAudio) {
129e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        mEncoder = MediaCodec::CreateByType(
130e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mCodecLooper, outputMIME.c_str(), true /* encoder */);
131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
132e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mEncoder == NULL) {
133e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            return ERROR_UNSUPPORTED;
134e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat = mInputFormat->dup();
138e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
139e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
140e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return OK;
141e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
142e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat->setString("mime", outputMIME.c_str());
144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
145f58cac48e5732dbc4a5f33eed9cd39f109146ca4Dave Burke    int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000);
1469f71aed36f7bb58fd8b077a5c6e414fc4af1805cDave Burke    int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 2500000);
14744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
14844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
14944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber          audioBitrate, videoBitrate);
15044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (isAudio) {
15244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", audioBitrate);
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
15444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", videoBitrate);
1554a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mOutputFormat->setInt32("frame-rate", 30);
156ee93c8c0f65cc1965ca09c9e33ae672f8bc9b88cDave Burke        mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
157c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber        mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1);
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->configure(
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mOutputFormat,
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* nativeWindow */,
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* crypto */,
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            MediaCodec::CONFIGURE_FLAG_ENCODE);
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->start();
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) {
188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = mNotify->dup();
189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("what", kWhatError);
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("err", err);
191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->post();
192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
194cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber// static
195cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huberbool Converter::IsSilence(const sp<ABuffer> &accessUnit) {
196cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    const uint8_t *ptr = accessUnit->data();
197cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    const uint8_t *end = ptr + accessUnit->size();
198cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    while (ptr < end) {
199cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (*ptr != 0) {
200cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            return false;
201cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
202cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        ++ptr;
203cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    }
204cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
205cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    return true;
206cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber}
207cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) {
209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerNotify:
211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
21296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
21396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
215e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (!mIsPCMAudio && mEncoder == NULL) {
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                ALOGV("got msg '%s' after encoder shutdown.",
21796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                      msg->debugString().c_str());
218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
21996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (what == MediaPuller::kWhatAccessUnit) {
22096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    sp<ABuffer> accessUnit;
22196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
22396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    void *mbuf;
22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                            && mbuf != NULL) {
22696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        ALOGV("releasing mbuf %p", mbuf);
227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
22896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        accessUnit->meta()->setPointer("mediaBuffer", NULL);
22996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
23096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        static_cast<MediaBuffer *>(mbuf)->release();
23196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        mbuf = NULL;
23296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    }
23396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
23496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
23596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
23696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
23796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == MediaPuller::kWhatEOS) {
23896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(NULL);
23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            } else {
24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK_EQ(what, MediaPuller::kWhatAccessUnit);
24596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                sp<ABuffer> accessUnit;
24796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
24896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0
25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                void *mbuf;
25196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
25296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        && mbuf != NULL) {
25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    ALOGI("queueing mbuf %p", mbuf);
25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif
25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
257cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION
258cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                if (!mIsVideo) {
259cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    if (IsSilence(accessUnit)) {
2608d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        if (mInSilentMode) {
2618d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            break;
2628d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        }
2638d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber
2648d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        int64_t nowUs = ALooper::GetNowUs();
2658d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber
2668d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        if (mFirstSilentFrameUs < 0ll) {
2678d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            mFirstSilentFrameUs = nowUs;
2688d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                        } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) {
2698d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            mInSilentMode = true;
2708d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            ALOGI("audio in silent mode now.");
2718d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                            break;
272cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        }
273cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    } else {
274cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        if (mInSilentMode) {
275cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                            ALOGI("audio no longer in silent mode.");
276cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        }
277cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        mInSilentMode = false;
278cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                        mFirstSilentFrameUs = -1ll;
279cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                    }
280cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                }
281cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif
282cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
28396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(accessUnit);
284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
28596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
28796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
28896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
292575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatEncoderActivity:
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
294575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 0
295575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            int64_t whenUs;
296575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            if (msg->findInt64("whenUs", &whenUs)) {
297575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                int64_t nowUs = ALooper::GetNowUs();
298575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                ALOGI("[%s] kWhatEncoderActivity after %lld us",
299575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                      mIsVideo ? "video" : "audio", nowUs - whenUs);
300575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            }
301575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif
302575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mDoMoreWorkPending = false;
30496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
30596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
30696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
30796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
30896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = doMoreWork();
310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err != OK) {
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notifyError(err);
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                scheduleDoMoreWork();
315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
319496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
320496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
32196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
32296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
32396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
32496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
325496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (mIsVideo) {
326496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGI("requesting IDR frame");
327496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                mEncoder->requestIDRFrame();
328496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
329496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
33296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatShutdown:
33396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
33496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("shutting down encoder");
335e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
336e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (mEncoder != NULL) {
337e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mEncoder->release();
338e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mEncoder.clear();
339e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
34096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
34196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            AString mime;
34296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(mInputFormat->findString("mime", &mime));
34396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("encoder (%s) shut down.", mime.c_str());
34496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
34596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
34696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
348d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() {
353e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
354e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        // There's no encoder involved in this case.
355e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return;
356e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
357e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mDoMoreWorkPending) {
359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mDoMoreWorkPending = true;
363575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
364575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 1
365575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mEncoderActivityNotify == NULL) {
366575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id());
367575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
368575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    mEncoder->requestActivityNotification(mEncoderActivityNotify->dup());
369575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#else
370575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id());
371575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    notify->setInt64("whenUs", ALooper::GetNowUs());
372575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    mEncoder->requestActivityNotification(notify);
373575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif
374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
376e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t Converter::feedRawAudioInputBuffers() {
377e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each
378e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    // and add a 4 byte header according to the wifi display specs.
379e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
380e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    while (!mInputBufferQueue.empty()) {
381e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
382e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
383e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
384e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        int16_t *ptr = (int16_t *)buffer->data();
385e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        int16_t *stop = (int16_t *)(buffer->data() + buffer->size());
386e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        while (ptr < stop) {
387e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            *ptr = htons(*ptr);
388e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ++ptr;
389e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
390e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
391e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kFrameSize = 2 * sizeof(int16_t);  // stereo
392e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kFramesPerAU = 80;
393e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        static const size_t kNumAUsPerPESPacket = 6;
394e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
395e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        if (mPartialAudioAU != NULL) {
396e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t bytesMissingForFullAU =
397e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                kNumAUsPerPESPacket * kFramesPerAU * kFrameSize
398e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                - mPartialAudioAU->size() + 4;
399e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
400e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t copy = buffer->size();
401e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if(copy > bytesMissingForFullAU) {
402e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                copy = bytesMissingForFullAU;
403e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
404e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
405e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(),
406e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                   buffer->data(),
407e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                   copy);
408e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
409e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy);
410e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
411e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
412e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
413e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t timeUs;
414e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
415e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
416e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
417e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            timeUs += copyUs;
418e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
419e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
420e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (bytesMissingForFullAU == copy) {
421e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                sp<AMessage> notify = mNotify->dup();
422e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setInt32("what", kWhatAccessUnit);
423e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setBuffer("accessUnit", mPartialAudioAU);
424e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->post();
425e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
426e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                mPartialAudioAU.clear();
427e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
428e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
429e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
430e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        while (buffer->size() > 0) {
431e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            sp<ABuffer> partialAudioAU =
432e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                new ABuffer(
433e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                        4
434e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                        + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU);
435e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
436e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            uint8_t *ptr = partialAudioAU->data();
437e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[0] = 0xa0;  // 10100000b
438e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[1] = kNumAUsPerPESPacket;
439e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[2] = 0;  // reserved, audio _emphasis_flag = 0
440e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
441e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kQuantizationWordLength = 0;  // 16-bit
442e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kAudioSamplingFrequency = 2;  // 48Khz
443e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            static const unsigned kNumberOfAudioChannels = 1;  // stereo
444e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
445e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            ptr[3] = (kQuantizationWordLength << 6)
446e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                    | (kAudioSamplingFrequency << 3)
447e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                    | kNumberOfAudioChannels;
448e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
449e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            size_t copy = buffer->size();
450e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (copy > partialAudioAU->size() - 4) {
451e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                copy = partialAudioAU->size() - 4;
452e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
453e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
454e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            memcpy(&ptr[4], buffer->data(), copy);
455e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
456e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            partialAudioAU->setRange(0, 4 + copy);
457e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->setRange(buffer->offset() + copy, buffer->size() - copy);
458e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
459e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t timeUs;
460e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
461e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
462e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            partialAudioAU->meta()->setInt64("timeUs", timeUs);
463e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
464e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0);
465e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            timeUs += copyUs;
466e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
467e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
468e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            if (copy == partialAudioAU->size() - 4) {
469e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                sp<AMessage> notify = mNotify->dup();
470e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setInt32("what", kWhatAccessUnit);
471e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->setBuffer("accessUnit", partialAudioAU);
472e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                notify->post();
473e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
474e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                partialAudioAU.clear();
475e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                continue;
476e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            }
477e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
478e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            mPartialAudioAU = partialAudioAU;
479e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        }
480e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
481e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
482e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return OK;
483e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber}
484e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() {
486e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    if (mIsPCMAudio) {
487e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        return feedRawAudioInputBuffers();
488e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    }
489e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (!mInputBufferQueue.empty()
491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && !mAvailEncoderInputIndices.empty()) {
492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t timeUs = 0ll;
499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t flags = 0;
500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (buffer != NULL) {
502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->data(),
506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->size());
507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            void *mediaBuffer;
509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    && mediaBuffer != NULL) {
511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ->setPointer("mediaBuffer", mediaBuffer);
513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                buffer->meta()->setPointer("mediaBuffer", NULL);
515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            flags = MediaCodec::BUFFER_FLAG_EOS;
518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = mEncoder->queueInputBuffer(
521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs, flags);
523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() {
533575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    status_t err;
534575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
535575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    for (;;) {
536575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        size_t bufferIndex;
537575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        err = mEncoder->dequeueInputBuffer(&bufferIndex);
538575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
539575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        if (err != OK) {
540575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
541575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.push_back(bufferIndex);
544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
546575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    feedEncoderInputBuffers();
547575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
548cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber    for (;;) {
549575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        size_t bufferIndex;
550cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        size_t offset;
551cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        size_t size;
552cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        int64_t timeUs;
553cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        uint32_t flags;
554cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        err = mEncoder->dequeueOutputBuffer(
555cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                &bufferIndex, &offset, &size, &timeUs, &flags);
556cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
557cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (err != OK) {
558cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            if (err == -EAGAIN) {
559cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber                err = OK;
560cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            }
561cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            break;
562cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatEOS);
567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> buffer = new ABuffer(size);
570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5728d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber            ALOGV("[%s] time %lld us (%.2f secs)",
5738d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber                  mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6);
574cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(buffer->data(),
576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   size);
578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mOutputFormat->setBuffer("csd-0", buffer);
581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> notify = mNotify->dup();
583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setInt32("what", kWhatAccessUnit);
584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setBuffer("accessUnit", buffer);
585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->post();
586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
589cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        mEncoder->releaseOutputBuffer(bufferIndex);
590cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber
591cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
592cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber            break;
593cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber        }
594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return err;
597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
599496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() {
600496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
601496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
602496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
604