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