Converter.cpp revision f58cac48e5732dbc4a5f33eed9cd39f109146ca4
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
2344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber#include <cutils/properties.h>
24d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceTextureClient.h>
25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/ICrypto.h>
26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaCodec.h>
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::Converter(
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &notify,
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ALooper> &codecLooper,
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &format)
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mInitCheck(NO_INIT),
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mCodecLooper(codecLooper),
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mInputFormat(format),
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber      mIsVideo(false),
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mDoMoreWorkPending(false) {
45496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    AString mime;
46496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    CHECK(mInputFormat->findString("mime", &mime));
47496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
48496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!strncasecmp("video/", mime.c_str(), 6)) {
49496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        mIsVideo = true;
50496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mInitCheck = initEncoder();
53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() {
56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mEncoder != NULL) {
57d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mEncoder->release();
58d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mEncoder.clear();
59d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
60a438123bd96c7faf145683876702387efe5628d9Andreas Huber
61a438123bd96c7faf145683876702387efe5628d9Andreas Huber    AString mime;
62a438123bd96c7faf145683876702387efe5628d9Andreas Huber    CHECK(mInputFormat->findString("mime", &mime));
63a438123bd96c7faf145683876702387efe5628d9Andreas Huber    ALOGI("encoder (%s) shut down.", mime.c_str());
64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const {
67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mInitCheck;
68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
7066e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const {
7166e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    return mEncoderInputBuffers.size();
7266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber}
7366e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const {
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mOutputFormat;
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
77d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
7844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) {
7944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    char val[PROPERTY_VALUE_MAX];
8044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    if (property_get(propName, val, NULL)) {
8144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        char *end;
8244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        unsigned long x = strtoul(val, &end, 10);
8344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
8444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        if (*end == '\0' && end > val && x > 0) {
8544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber            return x;
8644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        }
8744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    }
8844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
8944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    return defaultValue;
9044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber}
9144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() {
93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString inputMIME;
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(mInputFormat->findString("mime", &inputMIME));
95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString outputMIME;
97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool isAudio = false;
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
99d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_AUDIO_AAC;
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        isAudio = true;
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) {
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_VIDEO_AVC;
103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        TRESPASS();
105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mEncoder = MediaCodec::CreateByType(
108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mCodecLooper, outputMIME.c_str(), true /* encoder */);
109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mEncoder == NULL) {
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_UNSUPPORTED;
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat = mInputFormat->dup();
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat->setString("mime", outputMIME.c_str());
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
117f58cac48e5732dbc4a5f33eed9cd39f109146ca4Dave Burke    int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000);
1182a865ad8d45940bc824c02a8a8558cbcb97acc88Dave Burke    int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000);
11944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
12044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
12144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber          audioBitrate, videoBitrate);
12244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (isAudio) {
12444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", audioBitrate);
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
12644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", videoBitrate);
12772ff5903df5f409ea83f74c363a52f0745ced8b8Andreas Huber        mOutputFormat->setInt32("frame-rate", 24);
128ee93c8c0f65cc1965ca09c9e33ae672f8bc9b88cDave Burke        mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->configure(
134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mOutputFormat,
135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* nativeWindow */,
136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* crypto */,
137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            MediaCodec::CONFIGURE_FLAG_ENCODE);
138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->start();
144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::feedAccessUnit(const sp<ABuffer> &accessUnit) {
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFeedAccessUnit, id());
160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    msg->setBuffer("accessUnit", accessUnit);
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    msg->post();
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::signalEOS() {
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatInputEOS, id()))->post();
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) {
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = mNotify->dup();
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("what", kWhatError);
171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("err", err);
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->post();
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) {
176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatFeedAccessUnit:
178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> accessUnit;
180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mInputBufferQueue.push_back(accessUnit);
183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            feedEncoderInputBuffers();
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            scheduleDoMoreWork();
187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatInputEOS:
191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mInputBufferQueue.push_back(NULL);
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            feedEncoderInputBuffers();
195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            scheduleDoMoreWork();
197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatDoMoreWork:
201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mDoMoreWorkPending = false;
203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = doMoreWork();
204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err != OK) {
206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notifyError(err);
207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                scheduleDoMoreWork();
209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
213496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
214496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
215496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (mIsVideo) {
216496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGI("requesting IDR frame");
217496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                mEncoder->requestIDRFrame();
218496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
219496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
220496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
221496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() {
228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mDoMoreWorkPending) {
229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mDoMoreWorkPending = true;
233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatDoMoreWork, id()))->post(1000ll);
234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() {
237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (!mInputBufferQueue.empty()
238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && !mAvailEncoderInputIndices.empty()) {
239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t timeUs = 0ll;
246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t flags = 0;
247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (buffer != NULL) {
249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
25192f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber            ALOGV("in: %s timeUs = %lld us", mIsVideo ? "video" : "audio", timeUs);
25292f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber
253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->data(),
255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->size());
256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            void *mediaBuffer;
258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    && mediaBuffer != NULL) {
260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ->setPointer("mediaBuffer", mediaBuffer);
262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                buffer->meta()->setPointer("mediaBuffer", NULL);
264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            flags = MediaCodec::BUFFER_FLAG_EOS;
267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = mEncoder->queueInputBuffer(
270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs, flags);
272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() {
282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t bufferIndex;
283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->dequeueInputBuffer(&bufferIndex);
284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err == OK) {
286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.push_back(bufferIndex);
287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        feedEncoderInputBuffers();
288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t offset;
291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t size;
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int64_t timeUs;
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t flags;
294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->dequeueOutputBuffer(
295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            &bufferIndex, &offset, &size, &timeUs, &flags);
296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err == OK) {
298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatEOS);
301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
30392f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber            ALOGV("out: %s timeUs = %lld us", mIsVideo ? "video" : "audio", timeUs);
30492f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber
305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> buffer = new ABuffer(size);
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
307d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
308d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(buffer->data(),
309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   size);
311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mOutputFormat->setBuffer("csd-0", buffer);
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> notify = mNotify->dup();
316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setInt32("what", kWhatAccessUnit);
317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setBuffer("accessUnit", buffer);
318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->post();
319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
322d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mEncoder->releaseOutputBuffer(bufferIndex);
323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (err == -EAGAIN) {
324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = OK;
325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return err;
328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() {
331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
332496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
333496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
335