Converter.cpp revision 4a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5
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,
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &format)
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mInitCheck(NO_INIT),
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mCodecLooper(codecLooper),
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mInputFormat(format),
46496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber      mIsVideo(false),
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mDoMoreWorkPending(false) {
48496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    AString mime;
49496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    CHECK(mInputFormat->findString("mime", &mime));
50496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
51496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!strncasecmp("video/", mime.c_str(), 6)) {
52496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        mIsVideo = true;
53496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mInitCheck = initEncoder();
563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (mInitCheck != OK) {
583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (mEncoder != NULL) {
593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            mEncoder->release();
603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            mEncoder.clear();
613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() {
6696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(mEncoder == NULL);
6796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
68a438123bd96c7faf145683876702387efe5628d9Andreas Huber
6996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() {
7096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("shutdown");
7196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    (new AMessage(kWhatShutdown, id()))->post();
72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const {
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mInitCheck;
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
77d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
7866e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const {
7966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    return mEncoderInputBuffers.size();
8066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber}
8166e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const {
83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mOutputFormat;
84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
8644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) {
8744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    char val[PROPERTY_VALUE_MAX];
8844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    if (property_get(propName, val, NULL)) {
8944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        char *end;
9044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        unsigned long x = strtoul(val, &end, 10);
9144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
9244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        if (*end == '\0' && end > val && x > 0) {
9344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber            return x;
9444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        }
9544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    }
9644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
9744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    return defaultValue;
9844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber}
9944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() {
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString inputMIME;
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(mInputFormat->findString("mime", &inputMIME));
103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    AString outputMIME;
105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool isAudio = false;
106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_AUDIO_AAC;
108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        isAudio = true;
109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) {
110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        outputMIME = MEDIA_MIMETYPE_VIDEO_AVC;
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        TRESPASS();
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mEncoder = MediaCodec::CreateByType(
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mCodecLooper, outputMIME.c_str(), true /* encoder */);
117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mEncoder == NULL) {
119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_UNSUPPORTED;
120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat = mInputFormat->dup();
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mOutputFormat->setString("mime", outputMIME.c_str());
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
125f58cac48e5732dbc4a5f33eed9cd39f109146ca4Dave Burke    int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000);
1262a865ad8d45940bc824c02a8a8558cbcb97acc88Dave Burke    int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000);
12744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
12844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber    ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
12944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber          audioBitrate, videoBitrate);
13044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber
131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (isAudio) {
13244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", audioBitrate);
133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
13444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber        mOutputFormat->setInt32("bitrate", videoBitrate);
1354a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mOutputFormat->setInt32("frame-rate", 30);
136ee93c8c0f65cc1965ca09c9e33ae672f8bc9b88cDave Burke        mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
137c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber        mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1);
138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->configure(
143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mOutputFormat,
144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* nativeWindow */,
145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            NULL /* crypto */,
146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            MediaCodec::CONFIGURE_FLAG_ENCODE);
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->start();
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) {
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = mNotify->dup();
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("what", kWhatError);
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setInt32("err", err);
171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->post();
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) {
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
17696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerNotify:
177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
17896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
17996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
18196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
18296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                ALOGV("got msg '%s' after encoder shutdown.",
18396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                      msg->debugString().c_str());
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
18596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (what == MediaPuller::kWhatAccessUnit) {
18696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    sp<ABuffer> accessUnit;
18796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
18996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    void *mbuf;
19096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
19196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                            && mbuf != NULL) {
19296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        ALOGV("releasing mbuf %p", mbuf);
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
19496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        accessUnit->meta()->setPointer("mediaBuffer", NULL);
19596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
19696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        static_cast<MediaBuffer *>(mbuf)->release();
19796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        mbuf = NULL;
19896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    }
19996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
20096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
20196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
20296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
20396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == MediaPuller::kWhatEOS) {
20496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(NULL);
20596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
20696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
20796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
20896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
20996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            } else {
21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK_EQ(what, MediaPuller::kWhatAccessUnit);
21196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
21296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                sp<ABuffer> accessUnit;
21396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
21496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
21596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                void *mbuf;
21796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf)
21896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                        && mbuf != NULL) {
21996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    ALOGI("queueing mbuf %p", mbuf);
22096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
22196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif
22296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
22396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mInputBufferQueue.push_back(accessUnit);
224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                feedEncoderInputBuffers();
226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
22796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                scheduleDoMoreWork();
22896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatDoMoreWork:
233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mDoMoreWorkPending = false;
23596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
23696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
23796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
23896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            status_t err = doMoreWork();
241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (err != OK) {
243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notifyError(err);
244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                scheduleDoMoreWork();
246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
250496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
251496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
25296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (mEncoder == NULL) {
25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                break;
25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
256496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (mIsVideo) {
257496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGI("requesting IDR frame");
258496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                mEncoder->requestIDRFrame();
259496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
260496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
261496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
262496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
26396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatShutdown:
26496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
26596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("shutting down encoder");
26696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mEncoder->release();
26796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mEncoder.clear();
26896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
26996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            AString mime;
27096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(mInputFormat->findString("mime", &mime));
27196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            ALOGI("encoder (%s) shut down.", mime.c_str());
27296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
27396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
27496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() {
281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mDoMoreWorkPending) {
282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mDoMoreWorkPending = true;
28621daec5798f7e13c5ab6b513d27b3f79d4779bcaAndreas Huber    (new AMessage(kWhatDoMoreWork, id()))->post(10000ll);
287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() {
290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (!mInputBufferQueue.empty()
291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && !mAvailEncoderInputIndices.empty()) {
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<ABuffer> buffer = *mInputBufferQueue.begin();
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mInputBufferQueue.erase(mInputBufferQueue.begin());
294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t timeUs = 0ll;
299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t flags = 0;
300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (buffer != NULL) {
302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->data(),
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   buffer->size());
307d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
308d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            void *mediaBuffer;
309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    && mediaBuffer != NULL) {
311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ->setPointer("mediaBuffer", mediaBuffer);
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                buffer->meta()->setPointer("mediaBuffer", NULL);
315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            flags = MediaCodec::BUFFER_FLAG_EOS;
318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = mEncoder->queueInputBuffer(
321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
322d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs, flags);
323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() {
333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t bufferIndex;
334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = mEncoder->dequeueInputBuffer(&bufferIndex);
335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err == OK) {
337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mAvailEncoderInputIndices.push_back(bufferIndex);
338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        feedEncoderInputBuffers();
339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t offset;
342d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t size;
343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int64_t timeUs;
344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t flags;
345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    err = mEncoder->dequeueOutputBuffer(
346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            &bufferIndex, &offset, &size, &timeUs, &flags);
347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
348d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err == OK) {
349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatEOS);
352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> buffer = new ABuffer(size);
355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            buffer->meta()->setInt64("timeUs", timeUs);
356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(buffer->data(),
358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                   size);
360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mOutputFormat->setBuffer("csd-0", buffer);
363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> notify = mNotify->dup();
365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setInt32("what", kWhatAccessUnit);
366d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->setBuffer("accessUnit", buffer);
367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                notify->post();
368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mEncoder->releaseOutputBuffer(bufferIndex);
372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else if (err == -EAGAIN) {
373d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = OK;
374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return err;
377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
379496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() {
380496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
381496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
382496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
384