Converter.cpp revision 44b59fd9326026d3f82dec25cde48c589b0438e7
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),
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mDoMoreWorkPending(false) {
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mInitCheck = initEncoder();
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() {
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mEncoder != NULL) {
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mEncoder->release();
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mEncoder.clear();
51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const {
55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mInitCheck;
56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
57d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5866e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const {
5966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    return mEncoderInputBuffers.size();
6066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber}
6166e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
62d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const {
63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mOutputFormat;
64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
6644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) {
6744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    char val[PROPERTY_VALUE_MAX];
6844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    if (property_get(propName, val, NULL)) {
6944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        char *end;
7044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        unsigned long x = strtoul(val, &end, 10);
7144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
7244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        if (*end == '\0' && end > val && x > 0) {
7344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber            return x;
7444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        }
7544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    }
7644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
7744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    return defaultValue;
7844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber}
7944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
80d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() {
81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString inputMIME;
82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(mInputFormat->findString("mime", &inputMIME));
83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString outputMIME;
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool isAudio = false;
86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_AUDIO_AAC;
88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        isAudio = true;
89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) {
90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_VIDEO_AVC;
91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        TRESPASS();
93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mEncoder = MediaCodec::CreateByType(
96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mCodecLooper, outputMIME.c_str(), true /* encoder */);
97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mEncoder == NULL) {
99d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_UNSUPPORTED;
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat = mInputFormat->dup();
103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat->setString("mime", outputMIME.c_str());
104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
10544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 64000);
10644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 10000000);
10744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
10844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
10944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber          audioBitrate, videoBitrate);
11044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (isAudio) {
11244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", audioBitrate);
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
11444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", videoBitrate);
115e05a679401c7baeb0f82ce105eb20ae1ec863cdfAndreas Huber        mOutputFormat->setInt32("frame-rate", 60);
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mOutputFormat->setInt32("i-frame-interval", 3);  // Iframes every 3 secs
117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->configure(
122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mOutputFormat,
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* nativeWindow */,
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* crypto */,
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            MediaCodec::CONFIGURE_FLAG_ENCODE);
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->start();
132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::feedAccessUnit(const sp<ABuffer> &accessUnit) {
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFeedAccessUnit, id());
148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    msg->setBuffer("accessUnit", accessUnit);
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    msg->post();
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::signalEOS() {
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatInputEOS, id()))->post();
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) {
157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = mNotify->dup();
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("what", kWhatError);
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("err", err);
160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->post();
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) {
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatFeedAccessUnit:
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> accessUnit;
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mInputBufferQueue.push_back(accessUnit);
171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            feedEncoderInputBuffers();
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            scheduleDoMoreWork();
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatInputEOS:
179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mInputBufferQueue.push_back(NULL);
181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            feedEncoderInputBuffers();
183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            scheduleDoMoreWork();
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatDoMoreWork:
189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mDoMoreWorkPending = false;
191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = doMoreWork();
192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err != OK) {
194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notifyError(err);
195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                scheduleDoMoreWork();
197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() {
207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mDoMoreWorkPending) {
208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mDoMoreWorkPending = true;
212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatDoMoreWork, id()))->post(1000ll);
213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() {
216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (!mInputBufferQueue.empty()
217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && !mAvailEncoderInputIndices.empty()) {
218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t timeUs = 0ll;
225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t flags = 0;
226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (buffer != NULL) {
228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->data(),
232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->size());
233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            void *mediaBuffer;
235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    && mediaBuffer != NULL) {
237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ->setPointer("mediaBuffer", mediaBuffer);
239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                buffer->meta()->setPointer("mediaBuffer", NULL);
241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            flags = MediaCodec::BUFFER_FLAG_EOS;
244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = mEncoder->queueInputBuffer(
247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs, flags);
249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() {
259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t bufferIndex;
260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->dequeueInputBuffer(&bufferIndex);
261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err == OK) {
263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.push_back(bufferIndex);
264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        feedEncoderInputBuffers();
265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t offset;
268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t size;
269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int64_t timeUs;
270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t flags;
271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->dequeueOutputBuffer(
272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            &bufferIndex, &offset, &size, &timeUs, &flags);
273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err == OK) {
275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatEOS);
278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> buffer = new ABuffer(size);
281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(buffer->data(),
284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   size);
286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mOutputFormat->setBuffer("csd-0", buffer);
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> notify = mNotify->dup();
291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setInt32("what", kWhatAccessUnit);
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setBuffer("accessUnit", buffer);
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->post();
294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mEncoder->releaseOutputBuffer(bufferIndex);
298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (err == -EAGAIN) {
299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = OK;
300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return err;
303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
307