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> ¬ify, 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