Converter.cpp revision 2295ce2c6fcf07ffaa134440691a8cea5fe35b43
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, 41e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber const sp<AMessage> &format, 42e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber bool usePCMAudio) 43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mInitCheck(NO_INIT), 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNotify(notify), 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCodecLooper(codecLooper), 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInputFormat(format), 47496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mIsVideo(false), 48e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mIsPCMAudio(usePCMAudio), 49cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mDoMoreWorkPending(false) 50cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION 51cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ,mFirstSilentFrameUs(-1ll) 52cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ,mInSilentMode(false) 53cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif 54cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber { 55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber AString mime; 56496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber CHECK(mInputFormat->findString("mime", &mime)); 57496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 58496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (!strncasecmp("video/", mime.c_str(), 6)) { 59496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mIsVideo = true; 60496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 61496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 62e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(!usePCMAudio || !mIsVideo); 63e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInitCheck = initEncoder(); 653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (mInitCheck != OK) { 673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (mEncoder != NULL) { 683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber mEncoder->release(); 693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber mEncoder.clear(); 703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberConverter::~Converter() { 7596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(mEncoder == NULL); 7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber} 77a438123bd96c7faf145683876702387efe5628d9Andreas Huber 7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid Converter::shutdownAsync() { 7996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("shutdown"); 8096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber (new AMessage(kWhatShutdown, id()))->post(); 81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initCheck() const { 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mInitCheck; 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 8766e72bc85fb762876baff60ef29de729da93cf26Andreas Hubersize_t Converter::getInputBufferCount() const { 8866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber return mEncoderInputBuffers.size(); 8966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber} 9066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> Converter::getOutputFormat() const { 92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mOutputFormat; 93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 9544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huberstatic int32_t getBitrate(const char *propName, int32_t defaultValue) { 9644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber char val[PROPERTY_VALUE_MAX]; 9744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber if (property_get(propName, val, NULL)) { 9844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber char *end; 9944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber unsigned long x = strtoul(val, &end, 10); 10044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 10144b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber if (*end == '\0' && end > val && x > 0) { 10244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber return x; 10344b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber } 10444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber } 10544b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 10644b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber return defaultValue; 10744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber} 10844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::initEncoder() { 110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString inputMIME; 111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(mInputFormat->findString("mime", &inputMIME)); 112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString outputMIME; 114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isAudio = false; 115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { 116e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 117e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber outputMIME = MEDIA_MIMETYPE_AUDIO_RAW; 118e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } else { 119e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; 120e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber isAudio = true; 122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { 123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; 124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 128e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (!mIsPCMAudio) { 129e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder = MediaCodec::CreateByType( 130e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mCodecLooper, outputMIME.c_str(), true /* encoder */); 131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 132e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mEncoder == NULL) { 133e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return ERROR_UNSUPPORTED; 134e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat = mInputFormat->dup(); 138e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 139e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 140e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return OK; 141e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 142e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat->setString("mime", outputMIME.c_str()); 144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 145f58cac48e5732dbc4a5f33eed9cd39f109146ca4Dave Burke int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); 1462295ce2c6fcf07ffaa134440691a8cea5fe35b43Dave Burke int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000); 14744b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 14844b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber ALOGI("using audio bitrate of %d bps, video bitrate of %d bps", 14944b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber audioBitrate, videoBitrate); 15044b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (isAudio) { 15244b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber mOutputFormat->setInt32("bitrate", audioBitrate); 153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 15444b59fd9326026d3f82dec25cde48c589b0438e7Andreas Huber mOutputFormat->setInt32("bitrate", videoBitrate); 1554a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mOutputFormat->setInt32("frame-rate", 30); 156ee93c8c0f65cc1965ca09c9e33ae672f8bc9b88cDave Burke mOutputFormat->setInt32("i-frame-interval", 1); // Iframes every 1 secs 157c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1); 158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mEncoder->configure( 163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat, 164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber NULL /* nativeWindow */, 165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber NULL /* crypto */, 166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber MediaCodec::CONFIGURE_FLAG_ENCODE); 167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = mEncoder->start(); 173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = mEncoder->getInputBuffers(&mEncoderInputBuffers); 179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mEncoder->getOutputBuffers(&mEncoderOutputBuffers); 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::notifyError(status_t err) { 188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatError); 190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("err", err); 191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 194cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber// static 195cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huberbool Converter::IsSilence(const sp<ABuffer> &accessUnit) { 196cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber const uint8_t *ptr = accessUnit->data(); 197cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber const uint8_t *end = ptr + accessUnit->size(); 198cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber while (ptr < end) { 199cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (*ptr != 0) { 200cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber return false; 201cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 202cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ++ptr; 203cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 204cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 205cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber return true; 206cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber} 207cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::onMessageReceived(const sp<AMessage> &msg) { 209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatMediaPullerNotify: 211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 21296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber int32_t what; 21396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findInt32("what", &what)); 214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 215e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (!mIsPCMAudio && mEncoder == NULL) { 21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("got msg '%s' after encoder shutdown.", 21796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->debugString().c_str()); 218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 21996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == MediaPuller::kWhatAccessUnit) { 22096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<ABuffer> accessUnit; 22196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 22396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber void *mbuf; 22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber && mbuf != NULL) { 22696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("releasing mbuf %p", mbuf); 227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 22896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber accessUnit->meta()->setPointer("mediaBuffer", NULL); 22996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 23096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber static_cast<MediaBuffer *>(mbuf)->release(); 23196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mbuf = NULL; 23296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 23396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 23496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 23596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 23696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 23796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == MediaPuller::kWhatEOS) { 23896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mInputBufferQueue.push_back(NULL); 23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber feedEncoderInputBuffers(); 24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber scheduleDoMoreWork(); 24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } else { 24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK_EQ(what, MediaPuller::kWhatAccessUnit); 24596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<ABuffer> accessUnit; 24796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 24896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if 0 25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber void *mbuf; 25196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (accessUnit->meta()->findPointer("mediaBuffer", &mbuf) 25296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber && mbuf != NULL) { 25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("queueing mbuf %p", mbuf); 25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif 25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 257cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#if ENABLE_SILENCE_DETECTION 258cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (!mIsVideo) { 259cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (IsSilence(accessUnit)) { 2608d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber if (mInSilentMode) { 2618d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber break; 2628d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber } 2638d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber 2648d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 2658d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber 2668d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber if (mFirstSilentFrameUs < 0ll) { 2678d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mFirstSilentFrameUs = nowUs; 2688d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber } else if (nowUs >= mFirstSilentFrameUs + 10000000ll) { 2698d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mInSilentMode = true; 2708d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber ALOGI("audio in silent mode now."); 2718d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber break; 272cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 273cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } else { 274cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (mInSilentMode) { 275cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber ALOGI("audio no longer in silent mode."); 276cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 277cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mInSilentMode = false; 278cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mFirstSilentFrameUs = -1ll; 279cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 280cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 281cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber#endif 282cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 28396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mInputBufferQueue.push_back(accessUnit); 284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 28596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber feedEncoderInputBuffers(); 286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 28796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber scheduleDoMoreWork(); 28896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 292575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatEncoderActivity: 293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 294575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 0 295575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber int64_t whenUs; 296575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (msg->findInt64("whenUs", &whenUs)) { 297575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 298575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber ALOGI("[%s] kWhatEncoderActivity after %lld us", 299575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mIsVideo ? "video" : "audio", nowUs - whenUs); 300575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 301575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif 302575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mDoMoreWorkPending = false; 30496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 30596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mEncoder == NULL) { 30696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 30796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 30896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = doMoreWork(); 310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notifyError(err); 313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleDoMoreWork(); 315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 319496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 320496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 32196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mEncoder == NULL) { 32296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 32396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 32496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 325496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber if (mIsVideo) { 326496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber ALOGI("requesting IDR frame"); 327496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mEncoder->requestIDRFrame(); 328496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 329496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 33296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatShutdown: 33396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 33496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("shutting down encoder"); 335e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 336e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mEncoder != NULL) { 337e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder->release(); 338e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mEncoder.clear(); 339e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 34096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 34196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber AString mime; 34296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(mInputFormat->findString("mime", &mime)); 34396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("encoder (%s) shut down.", mime.c_str()); 34496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 34596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 34696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 348d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid Converter::scheduleDoMoreWork() { 353e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 354e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // There's no encoder involved in this case. 355e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return; 356e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 357e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mDoMoreWorkPending) { 359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return; 360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mDoMoreWorkPending = true; 363575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 364575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#if 1 365575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mEncoderActivityNotify == NULL) { 366575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id()); 367575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 368575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoder->requestActivityNotification(mEncoderActivityNotify->dup()); 369575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#else 370575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id()); 371575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber notify->setInt64("whenUs", ALooper::GetNowUs()); 372575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mEncoder->requestActivityNotification(notify); 373575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber#endif 374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 376e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t Converter::feedRawAudioInputBuffers() { 377e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // Split incoming PCM audio into buffers of 6 AUs of 80 audio frames each 378e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber // and add a 4 byte header according to the wifi display specs. 379e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 380e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (!mInputBufferQueue.empty()) { 381e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<ABuffer> buffer = *mInputBufferQueue.begin(); 382e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mInputBufferQueue.erase(mInputBufferQueue.begin()); 383e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 384e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int16_t *ptr = (int16_t *)buffer->data(); 385e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int16_t *stop = (int16_t *)(buffer->data() + buffer->size()); 386e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (ptr < stop) { 387e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber *ptr = htons(*ptr); 388e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ++ptr; 389e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 390e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 391e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kFrameSize = 2 * sizeof(int16_t); // stereo 392e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kFramesPerAU = 80; 393e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const size_t kNumAUsPerPESPacket = 6; 394e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 395e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mPartialAudioAU != NULL) { 396e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t bytesMissingForFullAU = 397e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber kNumAUsPerPESPacket * kFramesPerAU * kFrameSize 398e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber - mPartialAudioAU->size() + 4; 399e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 400e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t copy = buffer->size(); 401e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if(copy > bytesMissingForFullAU) { 402e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy = bytesMissingForFullAU; 403e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 404e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 405e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber memcpy(mPartialAudioAU->data() + mPartialAudioAU->size(), 406e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->data(), 407e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy); 408e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 409e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU->setRange(0, mPartialAudioAU->size() + copy); 410e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 411e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 412e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 413e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t timeUs; 414e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 415e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 416e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 417e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber timeUs += copyUs; 418e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->meta()->setInt64("timeUs", timeUs); 419e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 420e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (bytesMissingForFullAU == copy) { 421e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<AMessage> notify = mNotify->dup(); 422e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setInt32("what", kWhatAccessUnit); 423e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setBuffer("accessUnit", mPartialAudioAU); 424e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->post(); 425e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 426e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU.clear(); 427e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 428e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 429e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 430e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber while (buffer->size() > 0) { 431e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<ABuffer> partialAudioAU = 432e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber new ABuffer( 433e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 4 434e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber + kNumAUsPerPESPacket * kFrameSize * kFramesPerAU); 435e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 436e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber uint8_t *ptr = partialAudioAU->data(); 437e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[0] = 0xa0; // 10100000b 438e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[1] = kNumAUsPerPESPacket; 439e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[2] = 0; // reserved, audio _emphasis_flag = 0 440e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 441e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kQuantizationWordLength = 0; // 16-bit 442e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kAudioSamplingFrequency = 2; // 48Khz 443e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber static const unsigned kNumberOfAudioChannels = 1; // stereo 444e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 445e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber ptr[3] = (kQuantizationWordLength << 6) 446e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber | (kAudioSamplingFrequency << 3) 447e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber | kNumberOfAudioChannels; 448e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 449e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber size_t copy = buffer->size(); 450e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (copy > partialAudioAU->size() - 4) { 451e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber copy = partialAudioAU->size() - 4; 452e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 453e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 454e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber memcpy(&ptr[4], buffer->data(), copy); 455e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 456e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU->setRange(0, 4 + copy); 457e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->setRange(buffer->offset() + copy, buffer->size() - copy); 458e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 459e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t timeUs; 460e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 461e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 462e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU->meta()->setInt64("timeUs", timeUs); 463e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 464e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber int64_t copyUs = (int64_t)((copy / kFrameSize) * 1E6 / 48000.0); 465e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber timeUs += copyUs; 466e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber buffer->meta()->setInt64("timeUs", timeUs); 467e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 468e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (copy == partialAudioAU->size() - 4) { 469e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber sp<AMessage> notify = mNotify->dup(); 470e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setInt32("what", kWhatAccessUnit); 471e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->setBuffer("accessUnit", partialAudioAU); 472e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber notify->post(); 473e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 474e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber partialAudioAU.clear(); 475e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber continue; 476e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 477e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 478e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber mPartialAudioAU = partialAudioAU; 479e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 480e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 481e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 482e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return OK; 483e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber} 484e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::feedEncoderInputBuffers() { 486e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber if (mIsPCMAudio) { 487e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return feedRawAudioInputBuffers(); 488e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } 489e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (!mInputBufferQueue.empty() 491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber && !mAvailEncoderInputIndices.empty()) { 492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = *mInputBufferQueue.begin(); 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mInputBufferQueue.erase(mInputBufferQueue.begin()); 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t timeUs = 0ll; 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t flags = 0; 500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (buffer != NULL) { 502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(), 505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->data(), 506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->size()); 507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber void *mediaBuffer; 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer) 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber && mediaBuffer != NULL) { 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mEncoderInputBuffers.itemAt(bufferIndex)->meta() 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ->setPointer("mediaBuffer", mediaBuffer); 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->meta()->setPointer("mediaBuffer", NULL); 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber flags = MediaCodec::BUFFER_FLAG_EOS; 518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = mEncoder->queueInputBuffer( 521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(), 522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber timeUs, flags); 523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t Converter::doMoreWork() { 533575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber status_t err; 534575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 535575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber for (;;) { 536575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber size_t bufferIndex; 537575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber err = mEncoder->dequeueInputBuffer(&bufferIndex); 538575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 539575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (err != OK) { 540575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 541575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mAvailEncoderInputIndices.push_back(bufferIndex); 544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 546575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber feedEncoderInputBuffers(); 547575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 548cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber for (;;) { 549575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber size_t bufferIndex; 550cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber size_t offset; 551cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber size_t size; 552cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber int64_t timeUs; 553cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber uint32_t flags; 554cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber err = mEncoder->dequeueOutputBuffer( 555cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber &bufferIndex, &offset, &size, &timeUs, &flags); 556cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 557cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (err != OK) { 558cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (err == -EAGAIN) { 559cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber err = OK; 560cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 561cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber break; 562cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatEOS); 567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(size); 570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->meta()->setInt64("timeUs", timeUs); 571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5728d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber ALOGV("[%s] time %lld us (%.2f secs)", 5738d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber mIsVideo ? "video" : "audio", timeUs, timeUs / 1E6); 574cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(buffer->data(), 576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset, 577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size); 578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) { 580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatAccessUnit); 584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("accessUnit", buffer); 585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 589cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber mEncoder->releaseOutputBuffer(bufferIndex); 590cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber 591cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 592cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber break; 593cf2604f8940093e249ed7e5382c12ba544a48545Andreas Huber } 594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 599496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid Converter::requestIDRFrame() { 600496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber (new AMessage(kWhatRequestIDRFrame, id()))->post(); 601496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 602496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 604