Converter.cpp revision c6920dfdca378a168a2168f4a64d21af4d37d539
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> ¬ify, 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); 135ee178668818eb4f43ff40735405f8fc42372620fAndreas Huber mOutputFormat->setInt32("frame-rate", 60); 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; 286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (new AMessage(kWhatDoMoreWork, id()))->post(1000ll); 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